QC plots:
Description:
- The number of unique genes detected in each cell:
- Empty droplets and low quality cells often have very few genes and
many 0 counts
- Cell multiplets (doublets) often have very high gene count.
- If you work with the filtered counts matrix as a starting point you
will not find cells with <500 UMIs.
- User expectation:
- In general, you should have an expectation of home many genes/UMIs
the majority of your cells contain. Most of the time, The UMI counts per
cell should be at least ~500 (and ~200 genes), that is considered the
low end of what you should expect. However, cell that express extremely
low number of genes will have UMI count below ~500. The same is true for
a failed experiments with degraded RNAs. Thus the user should have an
clear expectation.
- The percentage of reads mapped to the mitochondrial genome:
- Often, dying cells (or low quality cells) have lots of mitochondrial
contamination, possibly due to loss of cytoplasmic RNA from perforated
cells. The reasoning is that mitochondria are larger than individual
transcript molecules and less likely to escape through tears in the cell
membrane.
- Note that for single-nuclei samples, MT genes are often still
present, but at much lower quantities when compared to single-cell
data.
- Mitochondrial QC metrics are calculates with the percentage of
counts originating from a set of features.
- We use the set of all genes starting with “MT-” or “mt-” as
mitochondrial genes (which have been inserted/manipulated in ALL MT
genes). (The Ensembl database is used to find the MT genes in the
species!)
Results:
- Barplots:
- Representing the distribution and number of gene counts, transcript
counts, and percentage of MT reads per cell. Generally, high fraction of
MT reads in combination with low gene/transcript counts indicate
stressed or dead cells. However, highly prolific stem or cancer-like
cell are often rich in MTs, whereas some immune cells such as
neutrophiles are in lower end of the spectrum in terms of gene and
transcript counts.
- The dashed red and orange lines represent the theoretical thresholds
(Red: 10% MT, 200 nGenes, 550 nUUMIs. Orange: 7.5% MT)



Here we will visualize the distribution of nGenes and nUMIs and the
complexity of the cells:
Description:
- Terminology:
- nFeature_RNA is the number of genes detected in each cell (violin
plot).
- nCount_RNA is the total number of molecules detected within a cell
(UMIs) (violin plot).
- percent.mt is the percentage of mitochondrial UMIs within a cell
(violin plot).
- Cell complexityis the proportion of nGenes raltive to the number of
transcripts (RNA-molecules/UMIs).
- Low complexity cells is a cell that has few genes, but more
transcripts.
- High complexity cells is a cell that more genes and less
transcripts.
- Dominant gene is a gene that has the hiighest expression in a cell
relative to the other genes.
Results:
- Violin plots:
- Low nFeature_RNA for a cell indicates that it may be dead/dying or
an empty droplet. It is usually accepted that cells that are poor
quality are likely to have low genes and UMIs per cell, and correspond
to the data points in the bottom left quadrant of the plot. Good cells
will generally exhibit both higher number of genes per cell and higher
numbers of UMIs. But be careful here, some cell types are known to have
low genes and UMIs.
- High nCount_RNA and/or nFeature_RNA indicates that the “cell” may in
fact be a doublet (or multiplet). But be careful again, some cell types
are known to have super high genes and UMIs (i.e. developing cells,
cancer, stem-cells).
- Percent-MT vs nGene / Percent-MT vs nUMI plot:
- Again, for bad cell we expect to see the high percentage MT with low
number of genes/UMIs (unless expected otherwise, e.g. cardiac
cells).
- The dashed read line represents a theoretical MT limit of 10% and
orange 5%.
- nUMIs vs nGenes plot (also log scaled version):
- Empty droplets and low quality cells often have very few genes and
many “0” genes/UMI counts (Minimum of 500 UMIs if you use the filtered
counts matrix).
- Cell multiplets (doublets) often have very high gene/UMI count.
- Notice that cell with the highest mitochondrial genes are located in
the bottom-left of the plot, indicating that these are truly bad cell
considering they contain high MT percentage, but low number of
genes/UMIs. Keep in mind that good cells could also have number of MT
genes, these cells are often activated cells
(i.e. Stem/cancer/cycling/developing cells). Now it could a little
troubling if the majority of your high MT cells also contain many
genes/UMIs, especially if you do not expect activated cell types in your
data. You have to be aware with the type of cell you are working
with.
- In the nUMI vs nGenes plot we can also see the complexity of the
dataset with potential errors. Generally, we expect a linear
relationship between the number of genes and UMIs in this plot. If cells
in the plot are skewed far from the middle line towards the bottom-right
this could mean that the experiment has captured very few number of
genes and those same genes have been sequenced multiple times.
Similarly, if the cells are skewed towards the top-left this could mean
that experiment has captured many genes, but they are not sequenced
deeply enough (which results in low number of UMIs). Keep in mind that
as a result of RNA degradation, a failed experiment could still give us
a good plots.
- The orange dashed lines show the theoretical lower limits of UMIs
(550) and genes (200). The yellow dashed lines show the upper and lower
quantiles of both number of genes and UMIs (default set between 2-98%).
If you choose filter the number of genes and UMIs by user-defined
quantiles, then the yellow dashed lines will be set at those
numbers.
- Complexity plot (the singular plot below):
- Complexity can also be visualized by dividing the nGenes by nUMIs
for each cell. Higher values indicate that we are getting shallower
coverage of more genes, and lower values mean that we are seeing fewer
genes overall.
- Generally, we expect the novelty score to be above 0.80 (indicated
with dashed red line).
- As there is a linear relationship between the number of genes and
transcripts for the majority of the cells, it is expected to find the
highest probability at a genes/transcript ratio between 0.85-0.95, even
for low-complexity cells. A large probability density at anything below
0.8 indicates a failed experiment, as insufficient genes have been
captured in proportion to transcript counts.
- Plotting complexity as function of percentage of counts per gene
(the first trio plots below):
- Complexity: Log10 - nUMIs vs nGenes: Again, make another plot as
before (log10 - nUMIs vs nGenes plot), but now we fit a linear model and
calculate the residual from the middle point for each cell. Now we can
clearly visualize which cells have more transcripts vs genes relative to
the middle-line (or vice versa). This is indicated by the strength of
the blue or red color.
- Residual vs Density: In this plot, we can see the frequency
(density) of cells as a function is the residuals (i.e. deviation from
the linear regression). What do you see here? A normal distribution or
skewed towards the left or right? This density plot is simply an
addition to the linear model and it is expected that you find the
largest density around 0, meaning that the majority of the cells were
indeed close to the middle line in the linear regression. Just like
before, if the graphs is skewed toward the left (negative residuals),
this means that you may have an undesired number of low-complexity
cells. Likewise, if the graph is skewed towards the right side (positive
residuals), then you may many high-complexity cells. Usually, such
behavior is related to some sort of failed experiment.
- Residual vs Percentage Largest genes: In this plot, for each cell,
we calculate the gene with the highest percentage of reads and put
against the residuals. You can now see a semi-density plot as before,
but now with the actual cells. Do you see a pattern here? Do you see any
low-complexity cells with a high percentage of a dominant gene? Ideally,
we expect a volcano plot centered around the middle. If you have many
low-complexity cells with a significantly inflated dominant gene, this
might indicate bad cells. But first, we have to find out winch dominant
gene they express to make a final conclusion if it is truly related to
some biological reason or technical.
- Plotting complexity and examining dominant genes (the final trio
plots below):
- Complexity by Largest Gene: This is the same linear plot as before,
but now we visualize the most dominant gene per cell (top 8 out of total
in the dataset). Do you see a pattern here or a specific gene that is
expressed in low or high complexity cells? Often, the unusual
populations in these plots can derive from the activity of a single
gene, so now you have a chance figure this out… If these genes happen to
be from a mitochondrial origin, then you are likely dealing with dead
cells. Likewise, high expression of MALAT1 can also indicate dead
cells.
- Residuals vs Percentage Largest Genes: Same as before, but now with
the dominant gene visualized. Which genes are the dominant ones in you
off target populations? And does this meet your expectation?
- Residuals vs Percentage Largest Genes + MT %: Same plot, but now
with percentage MT. Do the off-target cell populations show high
percentage of MT? And do find some correlation between this plot and the
dominant genes from before (MT genes)?


`geom_smooth()` using formula = 'y ~ x'
`geom_smooth()` using formula = 'y ~ x'




Visualize the highy variable genes:
Description:
We first employ a log normalization method that normalizes the
gene expression counts for each cell by the total expression and
multiply this by a scale factor of 10,000 and log transform it to
stabilize the variance so that larger values do not dominate over
smaller ones.
Then the top 2,500 genes (user-adjustable) with largest
standardize variance will be selected automatically and used for the
clustering. By selecting highly variable genes, we ensure that
house-keeping genes with similar expressions across different cells do
not interfere with the unsupervised clustering.
Note that there is no definitive answer on how many genes one
should include for clustering. Thus it is recommended to carefully
consider the right number or by trying a range of 2000-5000 variable
genes. Generally, low-complexity data (i.e. data with similar cells)
will have lower number of variable genes when compared to complex
tissue. By default, we will select 2500 highly variable genes.
Results:
- Most Variable Genes:
- The plot should not looks like a flat line. There should be a clear
distribution of the genes with the most highly variable on the top. If
there are no highly variable genes in your data, then you are likely
dealing with cells that have similar expression levels of the same
genes. This can drastically impact the clustering and ambient RNA
correction as most downstream steps are computed only on these
genes.
Finding variable features for layer counts

Unsupervised clustering: PCA
Description:
Here, we carry out a linear dimensional reduction using PCA on
the scaled data containing the most variable genes (as chosen
before):
- Before putting the highly variable genes into PCA, we will
specifically scale those genes so that they have a mean of 0 and a
variance of 1. More specifically, For each highly variable gene, a
regression model is build using that gene’s expression level across all
cells, and then shift the residual to zero and divided it by standard
deviation.
- We are essentially scaling and centering these genes in the dataset,
which standardizes the range of expression values. This will regresses
out unwanted sources of variation such as technical noise and each gene
will contributes similarly to the downstream steps. As a result, the PCA
and clustering will not be dominated by the signal of a few
highly-expressed genes.
The reason that we do a PCA is because we simply cannot work with
this ultra high dimensional data for the downstream analysis. Instead we
can look at which of the most variable genes explains most of the
variance in the data.
Note the PCA is a suitable method, but has some
disadvantages:
- (I still believe that ML would be a better option here, but it is
not benchmarked in single-cell data as an alternative to PCA).
- PCA is very popular, but fails to capture all signals considering
that 2D dimensionality reduction cannot capture faint signal.
Results:
- PCA elbow plot: We will find the optimal number of dimensions for
downstream analysis, based on:
- PC where change in percent variation is more than 1%.
- Or, PCs representing cumulative percent >90% and less than 5%
associated with the single PC.
- With each PC representing combined information of positive and
negative correlated gene sets, the top PCs represent strong compression
of the total dataset that can be used for further dimensionality
reduction and clustering. If you find less than 10 PCs in the elbow
plot, your data likely contains too few relevant genes for successful
clustering. After all, we are looking for genes that can explain the
variance in your cells, and if no such genes can be found (or too few of
them) then the downstream steps will have difficulties to find the
differences between your cells. However, if you are working with
low-complexity data (e.g. similar cell types in different biological
states) then you should to find fewer number of PCs.
- The dashed red line in the plot shows the optimal number PC
dimensions.

Final clustering (KNN (SNN)) using the most explained PCs and
projection onto UMAP:
Description:
- Original Louvain algorithm:
- Based on the Euclidean distance in the PCA space, the pipeline
carries out a K-nearest neighbor graph (k=20 by default) and refines the
edge between any two cells based on shared overlap between their
expression patterns using the traditional Jaccard similarity
technique.
- The clusters are then constructed by joining the groups
interactively until it fully converges using the Louvain algorithm.
Cells are then moved to a non-linear UMAP space for visualization. Here,
we find that by using a resolution of 0.8, Louvain does a decent job in
identifying sufficient number of communities for both high complexity
(porcine ileum, with immune) and low-complexity data (porcine ileum
organoid or tissue, no immune).
- To resolution of 0.8 is set as default, but more research is
required to use an adaptive resolution depending on the type of data as
this parameter could greatly impact the number preliminary clusters that
will be used by the ambient RNA correcting algorithm. As an experimental
feature, you are allowed to change the resolution, which will impact the
final number of cell clusters (not recommended).
- In case you end up with too few cluster by the default settings,
then it worth to try a resolution >0.8. If you have too few clusters,
the ambient RNA correction might become biased (more on this
later…).
Results:
- UMAP plots: Number of genes/UMIs/MTs are shown per cell within each
cluster:
- These plots can give us an idea which cells (within clusters)
contain low, medium or high number of genes and total UMIs.
- Note that high number of genes or UMIs is not necessarily a bad
thing, but is still highlighted with “purple”
- In case of a failed experiment (low number of genes) due to
significant population of cells with a low RNA content, these plots can
show which groups of cells are affected. And if the same clusters
contain high percentage MT genes, then it is likely that those cells are
low-quality or dead.
- How many cluster do you observe in total? Do you expect to see more
(or less) based on what you already know about your samples?




SoupX Ambient RNA Removal:
Description:
- Terminology:
- Total contamination is the fraction of ambient RNA (for each gene)
estimated from (semi)-empty droplets from the raw counts matrix.
- Contamination fractions is the the estimated the number transcripts
that are contributing to the previously calculated background
contamination (from empty droplets) using the expression of several
marker genes between cell-clusters where it does not belong. Here it is
assumed that the abundance of genes that make up the background are not
different between the cells.
- The aim of SoupX is to estimate what fraction of the transcripts are
derived as ambient in each droplet and to generate a corrected gene
counts matrix with the contaminated counts removed. The algorthm take
the following steps:
- It first calculates the expression profile of the total
contamination by estimating the ambient RNA expression from the raw
counts-matrix obtained from the CellRanger output. Regardless of the
user choice, in this step we always utilize the raw counts as this data
contains information of empty droplets, which is an excellent candidate
to analyze cell-free droplets that may contain ambient RNA for each
gene. (If for some reason the raw counts are not available, SoupX will
not run, and the pipeline will continue without the correction of
ambient RNA).
- Once the total contamination has been estimated, SoupX calculates
the cell specific contamination level by using the previously found cell
clusters. The point here is to find a set of genes in each cell that is
known not be expressed in others, and then estimate the contamination
fraction using the expression of that given gene in cells it does not
belong. If you have too few cluster (due to lack highly variable genes
and insufficient number PC dimensions), then it is advised to change
number of UMAP dimensions >0.8. Try it out and see if anything
improves. Usually, low number of clusters suggests low-complexity data
(either biological or technical reasons). Remember that you can also
leave out ambient RNA correction when dealing low-complexity if higher
UMAP dimensions do not improve anything.
- With the estimated contamination fraction and the background
expression profile at our disposal, the contaminated counts for each
gene within each cell can then be corrected.
- Keep in mind that working with the raw counts matrix only will
automatically filter cells/droplets that have less than 100 genes. This
is a less aggressive filtering when compared to using the filtered
counts matrix where Cellranger filtered out cells/droplets that contaied
<500 UMIs. For this reason, do not be shocked to find higher ambient
RNA contamination when working with the raw counts. The data will be
successfully corrected most of the time (unless you are dealing with
many degraded RNAs due to failed experiment).
Results:
Contamination Density plot (First plot):
Representing the probability distribution of estimated
contamination fraction. The probability density is calculated by the
aggregated set of genes per cells-cluster that have been used to find
the contamination fraction. The final contamination fraction is then
assigned to the one that occurs with the highest probability (indicated
with a vertical red line). A probability distribution with a flat line
(no clear peak) indicates failure of SoupX as none of the sets of genes
have a preferred contamination fraction, while true estimates are more
likely to have the same probability.
Barplot:
- Representing the percentage of ambient RNA detected and removed from
the data. A contamination level of around 10% is typical for non-nuclei
fresh tissue sample.
Affected Markers Soup Markers (UMAP):
- Representing the expression of marker candidates that were used for
the estimation of the contamination fraction and their level of
correction (pre and post Soup correction). By default, top 3 markers are
used for plotting, but the user is provided with the option to choose
anything between 0-100.
Affected User Genes (UMAP):
- Representing the expression of user-defined genes and level of
correction. For this to work the user must fill in the genes of interest
in the gene.txt file.
Most Affected Genes (UMAP):
- Representing the expression of most-affected genes and level of
correction. As the most-affected genes are not expressed by many cells,
these plots might not be very representative. This option is tuned off
by default, but the user may turn it on and select the number
plots.
Colors in the UMAP plots:
- Red dots - the gene is strongly corrected in the cell
- White dots - the gene is weakly corrected in the cell
- Grey dots - Nothing happened to that cell

[1] "Percentage of Ambient RNA (UMI) removed: 17.01 ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr"













Extensive filtering
Description:
By default, we automatically filter out cells with a percentage
of MT reads above 10%, with gene and transcript counts below the 2%
quantile as a lower limit. No filtering is applied on the higher limit
as these cells could represent doublets that we want to classify by
DoubletFinder instead of removing them by force. However, if the user
has prior knowledge on the dataset, filtering can also be applied by
user-defined cutoff values for the number of genes, transcripts and
percentage of MT reads. Additionally, the user may also adjust the upper
and lower quantiles for the parameters mentioned above. It is important
to consider that by removing cell in the upper limit by user-defined
cutoff values or quantiles, there is a good chance that true doublets
are being removed before identified in an algorithmic fashion.
Note that our default parameters have been performing well in
high complexity (porcine ileum and colon tissue, with immune) and low
complexity data (porcine ileum organoid) without loosing many cell-types
(including some rare immune cells with low number of
genes/transcripts).
Results:
- Now take a look in the chunk below… how many cells do you have? Is
it significantly lower than before?
- (The cells are called ‘samples’).
- (Ignore the inflated number of ‘feautures’. These are the number of
genes from two assays in Seurat).
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat
44080 features across 2637 samples within 2 assays
Active assay: RNA (22040 features, 2500 variable features)
3 layers present: counts, data, scale.data
1 other assay present: original.counts
2 dimensional reductions calculated: pca, umap
Multiplet Removal
Description:
The DoubletFinder algorithm first generates artificial doublets
by randomly merging different cells from the data. In total, one
artificial doublet is generated per four cells. We are essentially
creating a new dataset where artificial doublets are added to the mix.
By doing so, the artificial doublets resemble droplets that may contain
two completely different cell types. Arguably, the same process likely
occurs as true doublets form in the microfluidic container.
DoubletFinder then carries out PCAs using our previously determined
optimal number of PC-dimensions (during the unsupervised clustering
step). The PC distance matrix is then used to find artificial K-nearest
neighbors to define where the true and the artificial doublets share the
same neighborhood. This step is recursive and computational expensive
and thus we allow the user to choose the number of CPU-cores (4 cores by
default). Once complete, we remove the added artificial doublets and the
pre-defined proportion of identified real doublets from the
dataset.
Since there is a linear relationship between the percentage of
true doublets and number of recovered cells for the “Single Cell 3’ Gene
Expression Assay”, we implemented this linearity in the algorithm to
ensure the model does not over or underestimate the true doublets in the
dataset.
The relationship between the number of recovered cells and true
doublets is provided by 10X (https://kb.10xgenomics.com/hc/en-us/articles/360001378811-What-is-the-maximum-number-of-cells-that-can-be-profiled-).
We make a linear regression from this and implement it into
DoubletFinder.
Please increase the number of cores for this step if have many
cells. Finding artificial K-nearest neighbors during the parameter sweep
can be computationally expensive. The number of cores should NOT exceed
the available resources in your system provided to the pipeline. If you
do, then DoubletFinder will likely crash!
Results:
- Doublet UMAP plot:
- Representing the identified doublets within the preliminary cluster.
Often, the doublets are located on the edges or between other cell
population.
- Violin plots:
- Representing the scattered distribution of doublets and singlets as
a function of gene and transcript counts. Here it is expected that the
doublets contain more genes and transcripts when compared to
singlets.



ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr
Doublet Singlet
55 2582
Final filtering and QC plots
Results:
- In the chuck below, we will do another data filtering by taking out
the identified muultiplets in the dataset.
- Now you have can finally compare your results and number of cells
before and after filtering. It gives you an idea how aggressively you
have filtered your data.
- Likewise, you can compare the QC plots to what had before. Do you
see any improvement here?
- Remember that you can always change the parameters to your liking an
run it again.
- It is advised to try to annotate you cells using the pre-processed
data and see if you find your expected cells (in the right proportion).
If you think that you are missing some rare cells that contain few
genes/transcripts, then try to use the raw counts matrix as a starting
point. This will likely expose those cells that have been filtered out
by Cellrangers 500 UMI threshold. By using the raw matrix, the pipeline
will automatically remove all cells that have <100 genes. By doing
so, we ensure that you do not end up many low quality droplets. Even the
rarest cells usually do not contain less than 100 genes anyway. Feel
free to disagree and change the parameter to your liking. If you do not
change anything, then the threshold is always set at 100 genes. NEVER
TOUCH THIS PARAMETER IF YOU AEE WORKING WITH THE FILTERED COUNTS MATRIX!
You will always lose cells that contain few genes/transcripts.
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat
44080 features across 2582 samples within 2 assays
Active assay: RNA (22040 features, 2500 variable features)
3 layers present: counts, data, scale.data
1 other assay present: original.counts
2 dimensional reductions calculated: pca, umap





`geom_smooth()` using formula = 'y ~ x'
`geom_smooth()` using formula = 'y ~ x'




LS0tCm5hbWU6ICJTb21lIGlycmVsZXZhbnQgZ3V5IGZyb20gZWFydGggZG9pbmcgaGlzIHRoZXNpcyIKdGl0bGU6ICJTaW5nbGUgY2VsbC9udWNsZWkgUUMgYW5kIHByZS1wcm9jZXNzaW5nIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KICAgICAgICAgICAgYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIyMjIyMjIyBzbmFrZW1ha2UgcHJlYW1ibGUgc3RhcnQgKGF1dG9tYXRpY2FsbHkgaW5zZXJ0ZWQsIGRvIG5vdCBlZGl0KSAjIyMjIyMjIwpsaWJyYXJ5KG1ldGhvZHMpClNuYWtlbWFrZSA8LSBzZXRDbGFzcygKICAgICJTbmFrZW1ha2UiLAogICAgc2xvdHMgPSBjKAogICAgICAgIGlucHV0ID0gImxpc3QiLAogICAgICAgIG91dHB1dCA9ICJsaXN0IiwKICAgICAgICBwYXJhbXMgPSAibGlzdCIsCiAgICAgICAgd2lsZGNhcmRzID0gImxpc3QiLAogICAgICAgIHRocmVhZHMgPSAibnVtZXJpYyIsCiAgICAgICAgbG9nID0gImxpc3QiLAogICAgICAgIHJlc291cmNlcyA9ICJsaXN0IiwKICAgICAgICBjb25maWcgPSAibGlzdCIsCiAgICAgICAgcnVsZSA9ICJjaGFyYWN0ZXIiLAogICAgICAgIGJlbmNoX2l0ZXJhdGlvbiA9ICJudW1lcmljIiwKICAgICAgICBzY3JpcHRkaXIgPSAiY2hhcmFjdGVyIiwKICAgICAgICBzb3VyY2UgPSAiZnVuY3Rpb24iCiAgICApCikKc25ha2VtYWtlIDwtIFNuYWtlbWFrZSgKICAgIGlucHV0ID0gbGlzdCgnL2hvbWUvb3V0cHV0X3Rlc3QyJyksCiAgICBvdXRwdXQgPSBsaXN0KCcvaG9tZS9vdXRwdXRfdGVzdDIvaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50ci9zY1JOQS5uYi5odG1sJyksCiAgICBwYXJhbXMgPSBsaXN0KCcvaG9tZS9vdXRwdXRfdGVzdDInLCAnaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicsICdvdXRzL2ZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4JywgJ291dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4JywgJ2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAnU3VzIHNjcm9mYScsICcnLCAnJywgJycsICcnLCAnJywgJycsICcyJywgJzInLCAnL2hvbWUvcGlwZWxpbmUvYmFja3VwL21hcmtlcnMvZ2VuZS50eHQnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnNCcsICcnLCAnL2hvbWUvb3V0cHV0X3Rlc3QyL2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAicGFyZW50X2RpciIgPSAnL2hvbWUvb3V0cHV0X3Rlc3QyJywgInNhbXBsZV9uYW1lcyIgPSAnaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicsICJjb3VudHNfcGF0aF9maWx0ZXJlZCIgPSAnb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeCcsICJjb3VudHNfcGF0aF9yYXciID0gJ291dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4JywgImdyYXBoX25hbWVzIiA9ICdpbGV1bV9vcmdfcGlnLUczX0lMMV8xLWZpbHRlcmVkX3JlZl9HVEYtaW5jbF9pbnRyJywgImFuaW1hbCIgPSAnU3VzIHNjcm9mYScsICJ1c2VfcmF3X29ubHkiID0gJycsICJNSU5fY2VsbCIgPSAnJywgIk1JTl9mZWF0dXJlIiA9ICcnLCAibmZlYXR1cmVzIiA9ICcnLCAidW1hcF9yZXNvbHV0aW9uIiA9ICcnLCAibG93X2NvbXBsZXhpdHkiID0gJycsICJuX2hpZ2hseV9hZmZlY3RlZF9nZW5lcyIgPSAnMicsICJuX21hcmtlcnNfZ2VuZXMiID0gJzInLCAiY2Fub25pY2FsX21hcmtlcnMiID0gJy9ob21lL3BpcGVsaW5lL2JhY2t1cC9tYXJrZXJzL2dlbmUudHh0JywgImZlYXR1cmVfTE9XIiA9ICcnLCAiY291bnRfTE9XIiA9ICcnLCAiZmVhdHVyZV9ISUdIIiA9ICcnLCAiY291bnRfSElHSCIgPSAnJywgIm10X0NvbiIgPSAnJywgImZlYXR1cmVfcXVhbnRpbGVfbG93IiA9ICcnLCAiVU1JX3F1YW50aWxlX2xvdyIgPSAnJywgImZlYXR1cmVfcXVhbnRpbGVfaGlnaCIgPSAnJywgIlVNSV9xdWFudGlsZV9oaWdoIiA9ICcnLCAiQ1BVX2NvcmVzIiA9ICc0JywgInNraXBfRG91YmxldEZpbmRlciIgPSAnJywgImtuaXRzIiA9ICcvaG9tZS9vdXRwdXRfdGVzdDIvaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicpLAogICAgd2lsZGNhcmRzID0gbGlzdCgnL2hvbWUvb3V0cHV0X3Rlc3QyJywgJ2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAib3V0c19kaXIiID0gJy9ob21lL291dHB1dF90ZXN0MicsICJzYW1wbGVzIiA9ICdpbGV1bV9vcmdfcGlnLUczX0lMMV8xLWZpbHRlcmVkX3JlZl9HVEYtaW5jbF9pbnRyJyksCiAgICB0aHJlYWRzID0gMSwKICAgIGxvZyA9IGxpc3QoKSwKICAgIHJlc291cmNlcyA9IGxpc3QoJ3RtcGRpcicsICJ0bXBkaXIiID0gJy90bXAnKSwKICAgIGNvbmZpZyA9IGxpc3QoIm91dF9kaXJlY3RvcnkiID0gJycsICJyZWFkc19kaXJlY3RvcnkiID0gJycsICJzYW1wbGVfbmFtZXMiID0gJy9ob21lL291dHB1dF90ZXN0MicsICJjZWxscmFuZ2VyX2RpcmVjdG9yeSIgPSAnJywgInRyYW5zY3JpcHRvbWVfZGlyZWN0b3J5IiA9ICcnLCAibWFrZV9uZXdfcmVmIiA9ICcnLCAiZWRpdF9ndGYiID0gJycsICJndGZfZGlyZWN0b3J5IiA9ICcnLCAiZmFzdGFfZGlyZWN0b3J5IiA9ICcnLCAiZ2VuZV9iaW90eXBlIiA9ICdnZW5lX2Jpb3R5cGU6cHJvdGVpbl9jb2RpbmcnLCAiY2VsbHJhbmdlcl9jb3VudHNfb3B0aW9ucyIgPSAnJywgImFuaW1hbCIgPSAnU3VzIHNjcm9mYScsICJ1c2UucmF3Lm9ubHkiID0gJycsICJtaW4uY2VsbCIgPSAnJywgIm1pbi5mZWF0dXJlIiA9ICcnLCAibmZlYXR1cmVzIiA9ICcnLCAidW1hcC5yZXNvbHV0aW9uIiA9ICcnLCAibG93LmNvbXBsZXhpdHkiID0gJycsICJuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcyIgPSAnMicsICJuLm1hcmtlcnMuZ2VuZXMiID0gJzInLCAiZmVhdHVyZUxPVyIgPSAnJywgImNvdW50TE9XIiA9ICcnLCAiZmVhdHVyZUhJR0giID0gJycsICJjb3VudEhJR0giID0gJycsICJtdC5Db24iID0gJycsICJmZWF0dXJlLnF1YW50aWxlLmxvdyIgPSAnJywgIlVNSS5xdWFudGlsZS5sb3ciID0gJycsICJmZWF0dXJlLnF1YW50aWxlLmhpZ2giID0gJycsICJVTUkucXVhbnRpbGUuaGlnaCIgPSAnJywgInNraXAuRG91YmxldEZpbmRlciIgPSAnJywgIkNQVS5jb3JlcyIgPSAnNCcpLAogICAgcnVsZSA9ICdRQ19hbmRfUHJlX3Byb2Nlc3NpbmcnLAogICAgYmVuY2hfaXRlcmF0aW9uID0gYXMubnVtZXJpYyhOQSksCiAgICBzY3JpcHRkaXIgPSAnL2hvbWUvcGlwZWxpbmUvYmFja3VwL3NjcmlwdCcsCiAgICBzb3VyY2UgPSBmdW5jdGlvbiguLi4pewogICAgICAgIHdkIDwtIGdldHdkKCkKICAgICAgICBzZXR3ZChzbmFrZW1ha2VAc2NyaXB0ZGlyKQogICAgICAgIHNvdXJjZSguLi4pCiAgICAgICAgc2V0d2Qod2QpCiAgICB9CikKCiMjIyMjIyMjIHNuYWtlbWFrZSBwcmVhbWJsZSBlbmQgIyMjIyMjIyMjCgogICAgICAgICAgICBgYGAKCgpgYGB7ciBMb2FkIExpYnJhcmllcywgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoU2V1cmF0KSAKbGlicmFyeShkcGx5cikKbGlicmFyeShkYnBseXIpIApsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ3N1YmZuKSAKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCmxpYnJhcnkoU291cFgpICAgCmxpYnJhcnkoRG91YmxldEZpbmRlcikKCmxpYnJhcnkoQW5ub3RhdGlvbkh1YikKbGlicmFyeShCaW9jRmlsZUNhY2hlKQpsaWJyYXJ5KGVuc2VtYmxkYikgIApsaWJyYXJ5KERyb3BsZXRVdGlscykgCgpsaWJyYXJ5KGtuaXRyKSAKYGBgCgpgYGB7ciBpbXBvcnQgdGhlIHJlcXVpcmVtZW50cywgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgd2Ugc3BlY2lmeSB0aGUgcGF0aHMsIHBhcmFtZXRlcnMsIG5hbWVzIGFuZCBhbGwgZGVwZW5kZW5jaWVzCiMgLy8gVGhlIHB1cnBvc2UgaGVyZSBpcyB0byBzcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHdpdGhvdXQgdGhlIHVzZSBvZiBTbmFrZW1ha2UgKGZvciBkZWJ1Z2dpbmcpCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKc2Vzc2lvbkluZm8oKQojIFBhdGggMTBYIG91dHB1dDoKcGFyZW50X2RpcmVjdG9yeSA9IHNuYWtlbWFrZUBwYXJhbXMkcGFyZW50X2RpcgoKc2FtcGxlX3BhdGggPSBjKHNuYWtlbWFrZUBwYXJhbXMkc2FtcGxlX25hbWVzKSAjIHNhbXBsZSBmb2xkZXIKY291bnRzX3BhdGhfZmlsdGVyZWQgPSBzbmFrZW1ha2VAcGFyYW1zJGNvdW50c19wYXRoX2ZpbHRlcmVkICMgb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeApjb3VudHNfcGF0aF9yYXcgPSBzbmFrZW1ha2VAcGFyYW1zJGNvdW50c19wYXRoX3JhdyAjIG91dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4CgojIFNhbXBsZSBhbmQgcHJvamVjdCBuYW1lczoKc2FtcGxlX25hbWVzID0gYyhzbmFrZW1ha2VAcGFyYW1zJGdyYXBoX25hbWVzKSAjIFNhbXBsZSBuYW1lLCBmb3IgZ3JhcGhzLCAKCiMgQW5pbWFsIG5hbWVzIEVuc2VtYmw6CmFuaW1hbCA9IHNuYWtlbWFrZUBwYXJhbXMkYW5pbWFsICMgRm9yIEFubm90YXRpb25IdWIncyBxdWVyeSgpIGZ1bmN0aW9uCgojIFVzZSByYXc6IAp1c2UucmF3Lm9ubHkgPSBzbmFrZW1ha2VAcGFyYW1zJHVzZV9yYXdfb25seSAjIHVzZSByYXcgbWF0cml4IG9ubHkgaWYgc3BlY2lmaWVkIAojIEluaXRpYWwgZmlsdGVyaW5nOgptaW4uY2VsbCA9IHNuYWtlbWFrZUBwYXJhbXMkTUlOX2NlbGwKbWluLmZlYXR1cmUgPSBzbmFrZW1ha2VAcGFyYW1zJE1JTl9mZWF0dXJlICMgaWYgdXNpbmcgcmF3IG1hdHJpeCBvbmx5LCB0aGVuIHVzZSB0aGlzIHBhcmFtZXRlciAoc2V0IGl0IGF0IGFyb3VuZCAxMDApCgojIG4gaGlnaGx5IHZhcmlhYmxlIGZlYXR1cmVzCm5mZWF0dXJlcyA9IHNuYWtlbWFrZUBwYXJhbXMkbmZlYXR1cmVzCgojIFVNQVAgcmVzb2x1dGlvbgp1bWFwLnJlc29sdXRpb24gPSBzbmFrZW1ha2VAcGFyYW1zJHVtYXBfcmVzb2x1dGlvbgoKIyBGb3IgU291cFg6Cmxvdy5jb21wbGV4aXR5ID0gc25ha2VtYWtlQHBhcmFtcyRsb3dfY29tcGxleGl0eSAjICJ5ZXMiLCBubyBieSBkZWZhdWx0LCBza2lwIHNvdXBYIHdoZW4gbG93IGNvbXBsZXhpdHkKbi5oaWdobHlfYWZmZWN0ZWQuZ2VuZXMgPSBzbmFrZW1ha2VAcGFyYW1zJG5faGlnaGx5X2FmZmVjdGVkX2dlbmVzCm4ubWFya2Vycy5nZW5lcyA9IHNuYWtlbWFrZUBwYXJhbXMkbl9tYXJrZXJzX2dlbmVzCiNjYW5vbmljYWxfbWFya2VycyA9IGMoc25ha2VtYWtlQHBhcmFtcyRjYW5vbmljYWxfbWFya2VycykKY2Fub25pY2FsX21hcmtlcnMgPSBzY2FuKHNuYWtlbWFrZUBwYXJhbXMkY2Fub25pY2FsX21hcmtlcnMsIGNoYXJhY3RlcigpLCBxdW90ZSA9ICIiKSAjIGZyb20gLnR4dAoKIyBFeHRlbnNpdmUgZmlsdGVyaW5nOgpmZWF0dXJlTE9XID0gc25ha2VtYWtlQHBhcmFtcyRmZWF0dXJlX0xPVwpjb3VudExPVyA9IHNuYWtlbWFrZUBwYXJhbXMkY291bnRfTE9XIApmZWF0dXJlSElHSCA9IHNuYWtlbWFrZUBwYXJhbXMkZmVhdHVyZV9ISUdICmNvdW50SElHSCA9IHNuYWtlbWFrZUBwYXJhbXMkY291bnRfSElHSAptdC5Db24gPSBzbmFrZW1ha2VAcGFyYW1zJG10X0NvbgojIEJ5IHF1YW50aWxlCmZlYXR1cmUucXVhbnRpbGUubG93ID0gc25ha2VtYWtlQHBhcmFtcyRmZWF0dXJlX3F1YW50aWxlX2xvdwpVTUkucXVhbnRpbGUubG93ID0gc25ha2VtYWtlQHBhcmFtcyRVTUlfcXVhbnRpbGVfbG93CmZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IHNuYWtlbWFrZUBwYXJhbXMkZmVhdHVyZV9xdWFudGlsZV9oaWdoClVNSS5xdWFudGlsZS5oaWdoID0gc25ha2VtYWtlQHBhcmFtcyRVTUlfcXVhbnRpbGVfaGlnaAoKIyBEb3VibGV0RmluZGVyOgpDUFUuY29yZXMgPSBzbmFrZW1ha2VAcGFyYW1zJENQVV9jb3Jlcwpza2lwLkRvdWJsZXRGaW5kZXIgPSBzbmFrZW1ha2VAcGFyYW1zJHNraXBfRG91YmxldEZpbmRlciAjICJ5ZXMiIG5vIGJ5IGRlZmF1bHQsIHNraXAgRG91YmxldEZpbmRlciB3aGVuIGxvdyBjb21wbGV4aXR5CgpFeHBlcmltZW50YWwgPSAiIiAjIEFjY291bnRzIGZvciB0aGUgYmlvbG9neSAKCiMgUGFyYW1ldGVyIHJ1bGVzCiMgSWYgd2UgdXNlIHJhdyBvbmx5IGJ5IHVzZXIgZGVmaW5pdGlvbiBvciBvbmx5IGF2YWlsYWJsZSByYXcgbWF0cml4IAppZiAoKChzdHJfbGVuZ3RoKGNvdW50c19wYXRoX2ZpbHRlcmVkKSA9PSAwKSB8ICh1c2UucmF3Lm9ubHkgPT0gInllcyIgJiBzdHJfbGVuZ3RoKHVzZS5yYXcub25seSkgIT0gMCkpICYgbWluLmZlYXR1cmUgPT0gIiIpIHsKICBtaW4uZmVhdHVyZSA9ICIxMDAiIH0gZWxzZSB7bWluLmZlYXR1cmUgPSBtaW4uZmVhdHVyZX0KIyBJZiB0aGUgdXNlciBjaGFuZ2VzIHRoZSBVTUFQIHJlc29sdXRpb24KaWYgKHVtYXAucmVzb2x1dGlvbiA9PSAiIiAmIHN0cl9sZW5ndGgodW1hcC5yZXNvbHV0aW9uKSA9PSAwKSB7CiAgdW1hcC5yZXNvbHV0aW9uID0gIjAuOCIgfSBlbHNlIHt1bWFwLnJlc29sdXRpb24gPSB1bWFwLnJlc29sdXRpb259CiMgSWYgdGhlIHVzZXIgc2VsZWN0cyBtaW4uY2VsbCwgdGhlIHNvdXBYIHdpbGwgbm90IHJ1bjoKaWYgKHN0cl9sZW5ndGgobWluLmNlbGwpID4gMCkgewogIGxvdy5jb21wbGV4aXR5ID0gInllcyJ9IGVsc2Uge2xvdy5jb21wbGV4aXR5ID0gbG93LmNvbXBsZXhpdHkKICB9CgoKIyBDb252ZXJ0IHRvIG51bWVyaWMgdmFsdWVzCnVtYXAucmVzb2x1dGlvbiA8LSBhcy5udW1lcmljKHVtYXAucmVzb2x1dGlvbikKbmZlYXR1cmVzIDwtIGFzLm51bWVyaWMobmZlYXR1cmVzKQpuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcyA8LSBhcy5udW1lcmljKG4uaGlnaGx5X2FmZmVjdGVkLmdlbmVzKQpuLm1hcmtlcnMuZ2VuZXMgPC0gYXMubnVtZXJpYyhuLm1hcmtlcnMuZ2VuZXMpCmZlYXR1cmVMT1cgPC0gYXMubnVtZXJpYyhmZWF0dXJlTE9XKQpjb3VudExPVyA8LSBhcy5udW1lcmljKGNvdW50TE9XKQpmZWF0dXJlSElHSCA8LSBhcy5udW1lcmljKGZlYXR1cmVISUdIKQpjb3VudEhJR0ggPC0gYXMubnVtZXJpYyhjb3VudEhJR0gpCm10LkNvbiA8LSBhcy5udW1lcmljKG10LkNvbikKQ1BVLmNvcmVzIDwtIGFzLm51bWVyaWMoQ1BVLmNvcmVzKQpmZWF0dXJlLnF1YW50aWxlLmxvdyA8LSBhcy5udW1lcmljKGZlYXR1cmUucXVhbnRpbGUubG93KSAvIDEwMApVTUkucXVhbnRpbGUubG93IDwtIGFzLm51bWVyaWMoVU1JLnF1YW50aWxlLmxvdykgLyAxMDAKZmVhdHVyZS5xdWFudGlsZS5oaWdoIDwtIGFzLm51bWVyaWMoZmVhdHVyZS5xdWFudGlsZS5oaWdoKSAvIDEwMApVTUkucXVhbnRpbGUuaGlnaCA8LSBhcy5udW1lcmljKFVNSS5xdWFudGlsZS5oaWdoKSAvIDEwMAptaW4uY2VsbCA8LSBhcy5udW1lcmljKG1pbi5jZWxsKQptaW4uZmVhdHVyZSA8LSBhcy5udW1lcmljKG1pbi5mZWF0dXJlKQoKCiMgb3V0cHV0IGtuaXQKb3B0c19rbml0JHNldChyb290LmRpciA9IHNuYWtlbWFrZUBwYXJhbXMka25pdHMpCmBgYAoKYGBge3IgcHJlcGFyZSB0aGUgTVQgZ2VuZXMsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBpbmNsdWRlPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIGNhbGN1bGF0ZXMgYW5kIHJldHVybnMgYSB2ZWN0b3Igb2YgTWl0b2Nob25kcmlhbCBnZW5lcy4KIyAvLyBUaGUgZ2VuZSBuYW1lcyBmcm9tIG9yZ2FuaXNtIG9mIGludGVyZXN0IGFyZSBpbXBvcnRlZCBmcm9tIEFubm90YXRpb25IdWIKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIExvYWQgbWl0b2Nob25kcmlhbCBnZW5lcyAocHJvdGVpbiBjb2RpbmcpIAphbm4uaHViIDwtIEFubm90YXRpb25IdWIoYXNrID0gRkFMU0UsIGxvY2FsSHViID0gRkFMU0UpICMgY29ubmVjdCB0byBBbm5odWIKIyBBY2Nlc3MgdGhlIEVuc2VtYmwgZGF0YWJhc2UgZm9yIHBpZwphbm4uaHViLmRhdGFiYXNlIDwtIHF1ZXJ5KGFubi5odWIsIHBhdHRlcm4gPSBjKHBhc3RlKGFuaW1hbCksICJFbnNEYiIpLCBpZ25vcmUuY2FzZSA9IFRSVUUpCiMgQWNxdWlyZSB0aGUgbGF0ZXN0IGFubm90YXRpb24gZmlsZXMKaWQgPC0gYW5uLmh1Yi5kYXRhYmFzZSAlPiUKICAgICAgICBtY29scygpICU+JQogICAgICAgIHJvd25hbWVzKCkgJT4lCiAgICAgICAgdGFpbChuID0gMSkKIyBEb3dubG9hZGluZyB0aGUgRW5zZW1ibGRiIGRhdGFiYXNlCmVuc2VtYmwuZGF0YWJhc2UgPC0gYW5uLmh1YltbaWRdXQojIEV4dHJhY3QgZ2VuZS1sZXZlbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBkYXRhYmFzZQphbm5vdGF0aW9uc19NVCA8LSBnZW5lcyhlbnNlbWJsLmRhdGFiYXNlLCAKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuLnR5cGUgPSAiZGF0YS5mcmFtZSIpCiMgU2VsZWN0IGFubm90YXRpb25zIG9mIGludGVyZXN0CmFubm90YXRpb25zX01UIDwtIGFubm90YXRpb25zX01UICU+JQogICAgICAgIGRwbHlyOjpzZWxlY3QoZ2VuZV9uYW1lLCBzZXFfbmFtZSkKCiMgZmlsdGVyIGRhdGEgc2V0IGFuZCBrZWVwIE1UIHJvd3MKTVRfcm93cyA8LSB3aGljaChhbm5vdGF0aW9uc19NVCRzZXFfbmFtZSA9PSAiTVQiKSAjIGdldCByb3cgbnVtYmVyIG9mIGVsZW1lbnQgIk1UIiBpbnNpZGUKTVRfZ2VuZXMgPC0gYW5ub3RhdGlvbnNfTVQgJT4lIGRwbHlyOjpzbGljZShNVF9yb3dzKSAgIyBHZXQgTVQgZ2VuZXMgYnkgc2xpY2luZyBhbGwgdGhlIHJvd3MgdGhhdCBkbyBub3QgaGF2ZSAiTVQiCk1UX2dlbmVzIDwtIGFzLmNoYXJhY3RlcihNVF9nZW5lcyRnZW5lX25hbWVbTVRfZ2VuZXMkZ2VuZV9uYW1lICE9ICIiXSkgIyByZW1vdmUgZW1wdHkgIiIgdmFsdWVzCiNNVF9nZW5lcyA9IGMoIk5EMSIsICJORDIiLCAiQ09YMSIsICJDT1gyIiwgIkFUUDgiLCAiQVRQNiIsICJDT1gzIiwgIk5EMyIsICJORDRMIiwgIk5ENCIsICJORDUiLCAiTkQ2IiwgIkNZVEIiKQpgYGAKCmBgYHtyIExvYWQgaW4gcmF3IDEwWCBkYXRhLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBpbXBvcnRzIHRoZSB0aGUgZmlsdGVyZWQgYW5kIHJhdyBjb3VudCBtYXRyaWNlcyBnZW5lcmF0ZWQgYnkgQ2VsbFJhbmdlcgojIC8vIFRoZSBNaXRvY2hvbmRyaWEgZ2VuZXMgd2lsbCBhZGp1c3RlZCBieSBzdWJzdGl0dXRpbmcgYSBzdHJpbmcgb2YgIk1ULSIgdG8gdGhlIGluaXRpYWwgZ2VuZSBuYW1lCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKaWYgKHVzZS5yYXcub25seSA9PSAieWVzIiAmIHN0cl9sZW5ndGgodXNlLnJhdy5vbmx5KSAhPSAwKSB7CiAgICAjIElmIHdlIG9ubHkgd2FudCB0byB1c2UgcmF3IGRhdGUsIHRoZW4gcnVuIHRoaXMKICBkMTB4LmRhdGEgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICBkMTB4IDwtIFJlYWQxMFgoZmlsZS5wYXRoKHBhcmVudF9kaXJlY3RvcnksIGksIHBhc3RlKGNvdW50c19wYXRoX3JhdykpKQogIH0pCiAgZDEweC5kYXRhLnJhdyA8LSBzYXBwbHkoc2FtcGxlX3BhdGgsIGZ1bmN0aW9uKGkpewogIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpICMgYW5kIG1ha2UgYW5vdGhlciBjb3B5IG9mIHRoZSAicmF3X2ZlYXR1cmVfYmNfbWF0cml4LyIgKGZvciBTb3VwWCkKICB9KQp9IGVsc2UgewogIGlmIChzdHJfbGVuZ3RoKGNvdW50c19wYXRoX2ZpbHRlcmVkKSAhPSAwKSB7CiAgIyBMb2FkIHRoZSBmaWx0ZXJlZCBzaW5nbGUgY2VsbCBkYXRhIGZyb20gcGF0aCBpZiBhdmFpbGFibGUKICBkMTB4LmRhdGEgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICBkMTB4IDwtIFJlYWQxMFgoZmlsZS5wYXRoKHBhcmVudF9kaXJlY3RvcnksIGksIHBhc3RlKGNvdW50c19wYXRoX2ZpbHRlcmVkKSkpIAojICBjb2xuYW1lcyhkMTB4KSA8LSBwYXN0ZShzYXBwbHkoc3Ryc3BsaXQoY29sbmFtZXMoZDEweCksc3BsaXQ9Ii0iKSwnW1snLDFMKSxpLHNlcD0iLSIpCiMgIGQxMHggCiAgfSkKICBpZiAoc3RyX2xlbmd0aChjb3VudHNfcGF0aF9yYXcpICE9IDApIHsKICAgICMgQW5kIGxvYWQgdGhlIHJhdyBzaW5nbGUgY2VsbCBkYXRhIGZyb20gcGF0aCBpZiBhdmFpbGFibGUKICAgIGQxMHguZGF0YS5yYXcgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICAgIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpCiAgICB9KQogICAgfSBlbHNlIHsKICAgICAgIyBFbHNlIGxvYWQgdGhlIGZpbHRlcmVkIHNpbmdsZSBjZWxsIGRhdGEgZnJvbSBwYXRoIGlmIHJhdyBub3QgYXZhaWxhYmxlCiAgICAgIGQxMHguZGF0YS5yYXcgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICAgICAgZDEweCA8LSBSZWFkMTBYKGZpbGUucGF0aChwYXJlbnRfZGlyZWN0b3J5LCBpLCBwYXN0ZShjb3VudHNfcGF0aF9maWx0ZXJlZCkpKQogICAgICB9KQogICAgICB9Cn0gZWxzZSB7IAogICMgTG9hZCB0aGUgcmF3IHNpbmdsZSBjZWxsIGRhdGEgZnJvbSBwYXRoIGlmIGZpbHRlcmVkIG5vdCBhdmFpbGFibGUgYXQgYWxsIQogIGQxMHguZGF0YSA8LSBzYXBwbHkoc2FtcGxlX3BhdGgsIGZ1bmN0aW9uKGkpewogIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpCiAgfSkKICBkMTB4LmRhdGEucmF3IDwtIHNhcHBseShzYW1wbGVfcGF0aCwgZnVuY3Rpb24oaSl7CiAgZDEweCA8LSBSZWFkMTBYKGZpbGUucGF0aChwYXJlbnRfZGlyZWN0b3J5LCBpLCBwYXN0ZShjb3VudHNfcGF0aF9yYXcpKSkgIyBhbmQgbWFrZSBhbm90aGVyIGNvcHkgb2YgdGhlICJyYXdfZmVhdHVyZV9iY19tYXRyaXgvIiAoZm9yIFNvdXBYKQogIH0pCiAgfQogIH0KCiMgQWRkIG1pdG9jaG9uZHJpYWwgZ2VuZXMgdG8gZDEweC5kYXRhIG1hdHJpeCBhbmQgcmVtb3ZlIHVuZGVyc2NvcmVzIGZyb20gZ2VuZSBuYW1lcwpmb3IgKGkgaW4gc2FtcGxlX3BhdGgpIHsKICByb3duYW1lcy5kMTB4IDwtIHJvd25hbWVzKGQxMHguZGF0YVtbaV1dKSAjIFNhdmUgcm93IG5hbWVzCiAgTVQucG9zaXRpb25zLmQxMHggPC0gbmEub21pdChjKG1hdGNoKGMocGFzdGUoTVRfZ2VuZXMpKSwgcm93bmFtZXMuZDEweCkpKSAjIEZpbmQgaW5kZXggb2YgbWl0b2Nob25kcmlhbCBnZW5lcyBpbiBzYXZlZCByb3cgbmFtZXMKICAjIFVzZSBpbmRleCBvZiBtaXRvY2hvbmRyaWFsIGdlbmVzIGFuZCByZXBsYWNlIHRob3NlIGdlbmUgbmFtZXMgd2l0aCAiXk1ULSIgKyB0aGUgZ2VuZSBuYW1lIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQKICBpZiAoZ3JlcGwoIk1ULSIsIE1UX2dlbmVzWzFdKSA9PSBUUlVFKSB7CiAgcm93bmFtZXMuZDEweFtNVC5wb3NpdGlvbnMuZDEweF0gPC0gYyhwYXN0ZSgiIiwgTVRfZ2VuZXMsIHNlcCA9ICIiKSkgIyBLZWVwIGFzIGlzIGlmIE1ULQp9IGVsc2UgaWYgKGdyZXBsKCJtdC0iLCBNVF9nZW5lc1sxXSkgPT0gVFJVRSkgewogIHJvd25hbWVzLmQxMHhbTVQucG9zaXRpb25zLmQxMHhdIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBtdC0KICB9IGVsc2Ugcm93bmFtZXMuZDEweFtNVC5wb3NpdGlvbnMuZDEweF0gPC0gYyhwYXN0ZSgiTVQtIiwgTVRfZ2VuZXMsIHNlcCA9ICIiKSkgIyBhZGQgTVQtIHRvIGdlbmUgbmFtZQogIHJvdy5uYW1lcyhkMTB4LmRhdGFbW2ldXSkgPC0gcm93bmFtZXMuZDEweCAjIEFwcGVuZCB0aGUgbmV3IHJvdyBuYW1lcyB3aXRoIGNvcnJlY3QgTVQgbWFya3MgaW4gb3JpZ2luYWwgTWF0cml4CiAgcm93Lm5hbWVzKGQxMHguZGF0YVtbaV1dKSA8LSBnc3ViKCJfIiwgIi0iLCByb3duYW1lcyhkMTB4LmRhdGFbW2ldXSkpIAp9CiMgQW5kIGFkZCBtaXRvY2hvbmRyaWFsIGdlbmVzIHRvZCAxMHguZGF0YS5yYXcgbWF0cml4IGFuZCByZW1vdmUgdW5kZXJzY29yZXMgaW4gZ2VuZSBuYW1lcwpmb3IgKGkgaW4gc2FtcGxlX3BhdGgpIHsKICByb3duYW1lcy5kMTB4LnJhdyA8LSByb3duYW1lcyhkMTB4LmRhdGEucmF3W1tpXV0pIAogIE1ULnBvc2l0aW9ucy5kMTB4LnJhdyA8LSBuYS5vbWl0KGMobWF0Y2goYyhwYXN0ZShNVF9nZW5lcykpLCByb3duYW1lcy5kMTB4LnJhdykpKQogIGlmIChncmVwbCgiTVQtIiwgTVRfZ2VuZXNbMV0pID09IFRSVUUpIHsKICByb3duYW1lcy5kMTB4LnJhd1tNVC5wb3NpdGlvbnMuZDEweC5yYXddIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBNVC0KfSBlbHNlIGlmIChncmVwbCgibXQtIiwgTVRfZ2VuZXNbMV0pID09IFRSVUUpIHsKICByb3duYW1lcy5kMTB4LnJhd1tNVC5wb3NpdGlvbnMuZDEweC5yYXddIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBtdC0KICB9IGVsc2Ugcm93bmFtZXMuZDEweC5yYXdbTVQucG9zaXRpb25zLmQxMHgucmF3XSA8LSBjKHBhc3RlKCJNVC0iLCBNVF9nZW5lcywgc2VwID0gIiIpKSAjIGFkZCBNVC0gdG8gZ2VuZSBuYW1lCiAgcm93Lm5hbWVzKGQxMHguZGF0YS5yYXdbW2ldXSkgPC0gcm93bmFtZXMuZDEweC5yYXcKICByb3cubmFtZXMoZDEweC5kYXRhLnJhd1tbaV1dKSA8LSBnc3ViKCJfIiwgIi0iLCByb3duYW1lcyhkMTB4LmRhdGEucmF3W1tpXV0pKQp9CmBgYAoKIyMjIyBJbiB0aGUgY2h1Y2sgYmVsb3csIHdlIHdpbGwgbWFrZSBTZXVyYXQgb2JqZWN0cyBvZiBhbGwgc2FtcGxlcyAoYW5kIGFwcGx5IGJhc2ljIGZpbHRlcmluZyBiYXNlZCBvbiBhYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uIHRvIHJlbW92ZSBvdXRsaWVycyk6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBGb3IgZWFjaCBvYmplY3QsIHdlIGtlZXAgYWxsIGdlbmVzIHRoYXQgYXJlIGV4cHJlc3NlZCBpbiBhdCBsZWFzdCAwIGNlbGxzLCB0aHVzIHdlIGtlZXAgYWxsIGdlbmVzIGFzIHRoaXMgaXMgcmVxdWlyZWQgZm9yIHRoZSByZW1vdmFsIG9mIGFtYmllbnQgUk5BIChUaGUgQ2VsbHJhbmdlIGZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4IGRvZXMgbm90IGNvbnRhaW4gZ2VuZXMgdGhhdCBoYXZlIG5vIGV4cHJlc3Npb24gYWNyb3NzIGFsbCBjZWxscywgYnV0IHRoaXMgaXMgb2Z0ZW4gbm90IHRoZSBjYXNlIGZvciB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4LCBhbmQgY29uc2lkZXJpbmcgdGhhdCBib3RoIG1hdHJpY2VzIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGRldGVjdGlvbiBvZiBhbWJpZW50IFJOQSBpdCBpcyBub3Qgd2lzZSB0byBmaWx0ZXIgZ2VuZXMgd2l0aCAwIGNvdW50cyBpbiB0aGUgZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXguIEhvd2V2ZXIsIHRoaXMgaXMgbm90IGFuIGlzc3VlIGlmIHRoZSB1c2VyIGNob29zZXMgdG8gd29yayB3aXRoIHRoZSBmaWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeCB3aXRob3V0IGluY2x1ZGluZyB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4ZnJvbSBmcm9tIHRoZSB0aGUgc3RhcnQpLgoqIFNpbWlsYXJseSwgZm9yIG5vdyB3ZSB3YW50IHRvIGtlZXAgYWxsIGNlbGxzIHRoYXQgaGF2ZSBhdCBsZWFzdCAwIGdlbmVzIGV4cHJlc3NlZC4gV2Ugd2lsbCBsYXRlciBmaWx0ZXIgb3V0IGFsbCBjZWxscyB0aGF0IGhhdmUgbm90IGF0IGxlYXN0IHgtbnVtYmVyIG9mIGdlbmVzIGV4cHJlc3NlZCBhZnRlciBzdWNjZXNzZnVsbHkgcmVtb3ZpbmcgYW1iaWVudCBSTkEuIEtlZXAgaW4gbWluZCB0aGF0IGluIHJlYWxpdHkgbm8gY2VsbHMgd2lsbCBiZSBmb3VuZCB3aXRoIDAgZ2VuZXMgZXhwcmVzc2VkIGFueXdheSBjb25zaWRlcmluZyB0aGUgQ2VsbHJhbmdlciBwaXBlbGluZSBhbHJlYWR5IHJlbW92ZWQgZW1wdHkgZHJvcGxldHMgYW5kIGNlbGxzIGNvbnRhaW5pbmcgPDUwMCBVTUlzLgpIb3dldmVyLCBpZiB5b3UgY2hvb3NlIHRvIHdvcmsgd2l0aCB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4LCB5b3UgY2FuIGFjdHVhbGx5IGZpc2ggb3V0IGNlbGwgdGhhdCBtYXkgdHJ1bHkgaGF2ZSA8MTAwIGdlbmVzIGFuZCA8NTAwIFVNSXMuIEluIHRoYXQgY2FzZSwgd2Ugd2lsbCBtYWtlIHN1cmUgdGhhdCB3ZSByZW1vdmUgZHJvcGxldHMgKGNlbGxzKSB0aGF0IGhhdmUgPDEwMCBnZW5lcyBieSBkZWZhdWx0LiBZb3UgY2FuIGNob29zZSB0byBjaGFuZ2UgdGhpcyBwYXJhbWV0ZXIsIGJ1dCBpdCBpcyB2ZXJ5IHVubGlrZWx5IHRvIGZpbmQgcmVhbCBjZWxscyB3aXRoIDwxMDAgZ2VuZXMuIAoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogRnJvbSBub3cgb24geW91ICh0aGUgdXNlcikgc2hvdWxkIGtlZXAgYW4gZXllIG9uIHRoZSAidGhlIG51bWJlciBvZiBzYW1wbGVzIChjZWxscykiIGluIHRoZSBjaHVjayBiZWxvdy4gVGhlIG51bWJlciBvZiBzYW1wbGVzIGluIGVhY2ggZmlsdGVyaW5nIHN0ZXAgd2lsbCBnaXZlIHlvdSBhbiBpZGVhIGhvdyBtYW55IGNlbGwgeW91IGFyZSBsb3NpbmcgaW4gZWFjaCBzdGVwLgpgYGB7ciBjb252ZXJ0aW5nIDEwWCBkYXRhIGludG8gU2V1cmF0IG9iamVjdHMsIGVjaG89RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgaW1wb3J0cyB0aGUgbW9kaWZpZWQgZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXggYW5kIGNvbnZlcnRzIG90IHRvIGEgU2V1cmF0IG9iamVjdAojIC8vIFRoZSBTZXVyYXQgb2JqZWN0IHN0b3JlcyB0aGUgY291bnQgbWF0cmljZXMgaW4gc2xvdHMgCiMgLy8gQW55IG1vZGlmaWNhdGlvbiB0byB0aGUgY291bnQgbWF0cml4IHdpbGwgYXV0b21hdGljYWxseSBhZGQgaXQgdG8gYSBuZXcgc2xvdCAoZS5nLiBzY2FsaW5nIG9yIG5vcm1hbGl6YXRpb24pCiMgLy8gVGhpcyBjaHVuayBhbHNvIGNvbnRhaW5zIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIGV4cGVjdGVkIGRyb3BsZXRzIGNvbnRhaW5pbmcgbW9yZSB0aGFuIG9uZSBjZWxsCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBNYWtpbmcgU2V1cmF0IG9iamVjdHMgYW5kIHB1dHRpbmcgdGhlbSBpbiBhIHZlY3Rvcgpzb2JqX2xpc3QgPC0gbGlzdCgpICMgbWFrZSBlbXB0eSBsaXN0IHRvIGFwcGVuZCBTZXVyYXQgT2JqZWN0cyBpbiB0aGUgbG9vcCBiZWxvdwpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNhbXBsZV9wYXRoKSkgeyAgIyB3ZSBsb29wIGluIHJhbmdlIG9mIHNhbXBsZV9uYW1lLCBiZWNhdXNlIHRoYXQgZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgcmVwbGljYXRlcyB3ZSBoYXZlCiAgbmFtZSA8LSBwYXN0ZSgnJywgc2FtcGxlX3BhdGhbaV0sIHNlcD0nJykgIyBuYW1lIHRoZSBvYmplY3RzIGluIGxpc3QKICBzb2JqX2xpc3RbbmFtZV0gPC0gbGlzdChDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gZDEweC5kYXRhW1tpXV0sIHByb2plY3QgPSBwYXN0ZShzYW1wbGVfbmFtZXNbaV0pLCBtaW4uY2VsbHMgPSBpZiAobWluLmNlbGwgPj0gMCAmIGlzLm5hKG1pbi5jZWxsKSA9PSBGQUxTRSl7CiAgICBtaW4uY2VsbCA9IG1pbi5jZWxsfWVsc2V7bWluLmNlbGwgPSAwfSwgbWluLmZlYXR1cmVzID0gaWYgKG1pbi5mZWF0dXJlID49IDAgJiBpcy5uYShtaW4uZmVhdHVyZSkgPT0gRkFMU0UpewogICAgICBtaW4uZmVhdHVyZSA9IG1pbi5mZWF0dXJlfWVsc2V7bWluLmZlYXR1cmUgPSAwfSkpICMgYXBwZW5kIHRoZSBTZXVyYXQgb2JqZWN0cyBpbiBhIGxpc3Qgb2YgU2V1cmF0IE9iamVjdHMKIyAgICBwcmludChzb2JqX2xpc3QpICMgQVNTRVJUIENPREUgKFJFT01WRSBMQVRFUiEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhKQp9CgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFuZCByZXR1cm5zIGEgdmVjdG9yIG9mIHBlcmNlbnRhZ2Ugb2YgZXhwZWN0ZWQgZHJvcGxldHMgY29udGFpbmluZyBtb3JlIHRoYW4gb25lIGNlbGwgZm9yIGVhY2ggMTB4IGZpbGVzLgojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwojIC8vIFRoZSBlc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBtdWx0aXBsZXRzIGlzIGNhbGN1bGF0ZWQgYnkgYSBsaW5lYXIgZnVuY3Rpb24gcHJvdmlkZWQgYnkgMTBYIGJhc2VkIG9uIHRoZSBudW1iZXIgcmVjb3ZlcmVkIGNlbGxzCmVzdGltYXRlX3BlcmNlbnRhZ2VfbXVsdGlwbGV0cyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgZXN0aW1hdGVkX211bHRpcGxldHMgPC0gKGRpbShzb2JqKVsyXSAvIDEyNTApIC8gMTAwICMgZXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgbXVsdGlwbGV0cyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBudW1iZXIgb2YgcmVjb3ZlcmVkIGNlbGxzIGFjY29yZGluZyB0byAxMFggZ2Vub21pY3M6IGxpbmVhciBmb3JtdWxhOiAlbXVsdGlwbGV0ID0gbnVtLWNlbGxzIC8gMTI1MAogIHJldHVybihsaXN0KGVzdGltYXRlZF9tdWx0aXBsZXRzKSkKfQojIEV4ZWN1dGUgZXN0aW1hdGVfcGVyY2VudGFnZV9tdWx0aXBsZXRzIGZ1bmN0aW9uCnBlcmNlbnQubXVsdGlwbGV0cyA8LSBzYXBwbHkoc29ial9saXN0LCBlc3RpbWF0ZV9wZXJjZW50YWdlX211bHRpcGxldHMpCnByaW50KHNvYmpfbGlzdCkKYGBgCiogQWZ0ZXIgZmlsdGVyaW5nIHRoZSBvYmplY3RzIGJhc2VkIG9uIHRoZSBhYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uLCB5b3UgY2FuIHRha2UgYSBjbG9zZSBsb29rIGF0IHRoZSBudW1iZXIgb2Ygc2FtcGxlcyBhZ2FpbiBhbmQgc2VlIGhvdyBtYW55IGNlbGwgd2VyZSByZW1vdmVkIHdoZW4gY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIHN0ZXA6CiAgLSBBYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uIHRocmVzaG9sZCBpcyBzZXQgaW4gYSB3YXkgdG8gcmVtb3ZlIHRoZSB2ZXJ5IGV4dHJlbWUgY2VsbHMgaW4gY2FzZSBzb21lIHNsaXBwZWQgdGhyb3VnaCB0aGUgQ2VsbHJhbmdlciBmaWx0ZXJpbmcuCiAgLSBUaGUgZmlsdGVyaW5nIGhlcmUgd2lsbCBvZnRlbiBub3QgcmVtb3ZlIG1vcmUgdGhhbiAyMC01MCBjZWxscyBhbmQgd2lsbCBub3QgaW1wYWN0IHRoZSBwcmUtcHJvY2Vzc2luZyBhbGdvcml0aG1zLiAKICAtIFRoaXMgc3RlcCBkb2VzIGhhdmUgZ3JlYXQgaW1wYWN0IGlmIHlvdSBjaG9vc2UgdG8gd29yayB3aXRoIHRoZSByYXdfZmVhdHVyZV9iY19tYXRyaXguIEZvciBhIGdvb2QgcmVhc29uIHRvby4uLiB1bmxlc3MgeW91IGFyZSBpbiBsb3ZlIHdpdGggZW1wdHkgZHJvcGxldHMuLi4KCiogQWdhaW4sIGluIHRoZSBjaHVuayBiZWxvdyB5b3Ugc2hvdWxkIHNlZSBoYXcgbWFueSBjZWxscyB5b3UgbG9zdC4gd2hlbiBjb21wYXJlZCB0byB0aGUgcHJldmlvdXMgc3RlcC4gCmBgYHtyIGFwcGx5IGJhc2ljIGZpbHRlcmluZyB0byBlYWNoIFNldWF0IG9iamVjdCwgZWNobz1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBpbXBvcnRzIHRoZSBwcmV2aW91c2x5IG1hZGUgb2JqZWN0IGFuZCByZW1vdmVzIGV4dHJlbWUgY2VsbHMgYmFzZWQgb24gQWJzb2x1dGUgbWVkaWFuIGRldmlhdGlvbgojIC8vIFRoZSBmaWx0ZXJpbmcgaXMgdmVyeSBzdWJ0bGUgYW5kIHdpbGwgd2lsbCBvbmx5IHJlbW92ZSB0aGUgdmVyeSBleHRyZW1lIGNlbGxzCiMgLy8gT2Z0ZW4gbm8gbW9yZSB0aGFuIGEgaGFuZGZ1bCBvZiBjZWxscyB3aWxsIGJlIHJlbW92ZWQgYW5kIHRoaXMgd2lsbCBub3QgaW1wYWN0IHRoZSBwcmUtcHJvY2Vzc2luZyBhbGdvcml0aG1zCiMgLy8gVGhpcyBjaHVuayBpcyBleGVjdXRlZCB1c2luZyB0d28gc2VwYXJhdGUgZnVuY3Rpb25zIChpZGVudGlmeWluZyBhbmQgcmVtb3Zpbmcgb3V0bGllcikKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIGZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gRnVuY3Rpb24gdG8gY2FsY3VsYXRlIGFuZCByZXR1cm4gb3V0bGllcnMgYmFzZWQgb24gYWJzb2x1dGUgbWVkaWFuIGRldmlhdGlvbnMKIyAvLyBUaGUgaW5wdXQgZmlsZSBtdXN0IGEgdmVjdG9yIG9mIG9iamVjdHMKY2FsX291dGxpZXIgPC0gZnVuY3Rpb24oc29iaiwgbWV0cmljLCBubWFkcyl7CiAgTSA8LSBzb2JqQG1ldGEuZGF0YVtbbWV0cmljXV0KICBtZWRpYW5fTSA8LSBtZWRpYW4oTSwgbmEucm0gPSBUUlVFKQogIG1hZF9NIDwtIG1hZChNLCBuYS5ybSA9IFRSVUUpCiAgb3V0bGllciA8LSAoTSA8IChtZWRpYW5fTSAtIG5tYWRzICogbWFkX00pKSB8IChNID4gKG1lZGlhbl9NICsgbm1hZHMgKiBtYWRfTSkpCiAgcmV0dXJuKG91dGxpZXIpCn0KCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBGdW5jdGlvbiB0byByZW1vdmUgb3V0bGllcnMgYW5kIHJldHVybiBjbGVhbiBvYmplY3QKIyAvLyBUaGUgaW5wdXQgZmlsZSBtdXN0IGEgdmVjdG9yIG9mIG9iamVjdHMKcmVtX291dGxpZXIgPC0gZnVuY3Rpb24oc29iail7CiAgCiMgIHNvYmogPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgc2FtcGxlX25hbWVzLCAib3V0cy9yYXdfZmVhdHVyZV9iY19tYXRyaXgvIikpCiMgIHNvYmogPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHNvYmosIG1pbi5jZWxscyA9IDEwLCBtaW4uZmVhdHVyZXMgPSAyMDApCiMgIHNvYmokc2FtcGxlX25hbWVzIDwtIHNhbXBsZV9uYW1lcwogIAogICMgYWRkIGJRQyBtZXRyaWNzCiAgc29iaiRsb2cxcF90b3RhbF9jb3VudHMgPC0gbG9nMXAoc29iakBtZXRhLmRhdGEkbkNvdW50X1JOQSkKICBzb2JqJGxvZzFwX25fZ2VuZXNfYnlfY291bnRzIDwtIGxvZzFwKHNvYmpAbWV0YS5kYXRhJG5GZWF0dXJlX1JOQSkKIyAgc29ialtbInBlcmNlbnQubXQiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc29iaiwgcGF0dGVybiA9ICJNSVRPQ0hPTkRSSUFMIikKICAKICAjIEZpbmQgb3V0bGllcnMgdXNpbmcgdGhlICJjYWxfb3V0bGllciIgZnVuY3Rpb246CiAgYm9vbF92ZWN0b3IgPC0gIWNhbF9vdXRsaWVyKHNvYmosICJsb2cxcF90b3RhbF9jb3VudHMiLCA1KSAmICFjYWxfb3V0bGllcihzb2JqLCAibG9nMXBfbl9nZW5lc19ieV9jb3VudHMiLCA1KSAjICYgIWNhbF9vdXRsaWVyKHNvYmosICJwZXJjZW50Lm10IiwgMTApCiAgc29iaiA8LSBzdWJzZXQoc29iaiwgY2VsbHMgPSB3aGljaChib29sX3ZlY3RvcikpCiAgcmV0dXJuKHNvYmopCn0KCiMgUHJpbnQgdGhlIG91dHB1dCBmb3IgY29udHJvbApzb2JqX2xpc3QgPC0gc2FwcGx5KHNvYmpfbGlzdCwgcmVtX291dGxpZXIpCmZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc29ial9saXN0KSkgewogIHByaW50KHNvYmpfbGlzdFtpXSkKfQpgYGAKCiMjIyMgUUMgcGxvdHM6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBUaGUgbnVtYmVyIG9mIHVuaXF1ZSBnZW5lcyBkZXRlY3RlZCBpbiBlYWNoIGNlbGw6IAogIC0gRW1wdHkgZHJvcGxldHMgYW5kIGxvdyBxdWFsaXR5IGNlbGxzIG9mdGVuIGhhdmUgdmVyeSBmZXcgZ2VuZXMgYW5kIG1hbnkgMCBjb3VudHMKICAtIENlbGwgbXVsdGlwbGV0cyAoZG91YmxldHMpIG9mdGVuIGhhdmUgdmVyeSBoaWdoIGdlbmUgY291bnQuCiAgLSBJZiB5b3Ugd29yayB3aXRoIHRoZSBmaWx0ZXJlZCBjb3VudHMgbWF0cml4IGFzIGEgc3RhcnRpbmcgcG9pbnQgeW91IHdpbGwgbm90IGZpbmQgY2VsbHMgd2l0aCA8NTAwIFVNSXMuCgoqIFVzZXIgZXhwZWN0YXRpb246CiAgLSBJbiBnZW5lcmFsLCB5b3Ugc2hvdWxkIGhhdmUgYW4gZXhwZWN0YXRpb24gb2YgaG9tZSBtYW55IGdlbmVzL1VNSXMgdGhlIG1ham9yaXR5IG9mIHlvdXIgY2VsbHMgY29udGFpbi4gTW9zdCBvZiB0aGUgdGltZSwgVGhlIFVNSSBjb3VudHMgcGVyIGNlbGwgc2hvdWxkIGJlIGF0IGxlYXN0IH41MDAgKGFuZCB+MjAwIGdlbmVzKSwgdGhhdCBpcyBjb25zaWRlcmVkIHRoZSBsb3cgZW5kIG9mIHdoYXQgeW91IHNob3VsZCBleHBlY3QuIEhvd2V2ZXIsIGNlbGwgdGhhdCBleHByZXNzIGV4dHJlbWVseSBsb3cgbnVtYmVyIG9mIGdlbmVzIHdpbGwgaGF2ZSBVTUkgY291bnQgYmVsb3cgfjUwMC4gVGhlIHNhbWUgaXMgdHJ1ZSBmb3IgYSBmYWlsZWQgZXhwZXJpbWVudHMgd2l0aCBkZWdyYWRlZCBSTkFzLiBUaHVzIHRoZSB1c2VyIHNob3VsZCBoYXZlIGFuIGNsZWFyIGV4cGVjdGF0aW9uLgogIAoqIFRoZSBwZXJjZW50YWdlIG9mIHJlYWRzIG1hcHBlZCB0byB0aGUgbWl0b2Nob25kcmlhbCBnZW5vbWU6IAogIC0gT2Z0ZW4sIGR5aW5nIGNlbGxzIChvciBsb3cgcXVhbGl0eSBjZWxscykgaGF2ZSBsb3RzIG9mIG1pdG9jaG9uZHJpYWwgY29udGFtaW5hdGlvbiwgcG9zc2libHkgZHVlIHRvIGxvc3Mgb2YgY3l0b3BsYXNtaWMgUk5BIGZyb20gcGVyZm9yYXRlZCBjZWxscy4gVGhlIHJlYXNvbmluZyBpcyB0aGF0IG1pdG9jaG9uZHJpYSBhcmUgbGFyZ2VyIHRoYW4gaW5kaXZpZHVhbCB0cmFuc2NyaXB0IG1vbGVjdWxlcyBhbmQgbGVzcyBsaWtlbHkgdG8gZXNjYXBlIHRocm91Z2ggdGVhcnMgaW4gdGhlIGNlbGwgbWVtYnJhbmUuCiAgLSBOb3RlIHRoYXQgZm9yIHNpbmdsZS1udWNsZWkgc2FtcGxlcywgTVQgZ2VuZXMgYXJlIG9mdGVuIHN0aWxsIHByZXNlbnQsIGJ1dCBhdCBtdWNoIGxvd2VyIHF1YW50aXRpZXMgd2hlbiBjb21wYXJlZCB0byBzaW5nbGUtY2VsbCBkYXRhLgogIC0gTWl0b2Nob25kcmlhbCBRQyBtZXRyaWNzIGFyZSBjYWxjdWxhdGVzIHdpdGggdGhlIHBlcmNlbnRhZ2Ugb2YgY291bnRzIG9yaWdpbmF0aW5nIGZyb20gYSBzZXQgb2YgZmVhdHVyZXMuCiAgLSBXZSB1c2UgdGhlIHNldCBvZiBhbGwgZ2VuZXMgc3RhcnRpbmcgd2l0aCAiTVQtIiBvciAibXQtIiBhcyBtaXRvY2hvbmRyaWFsIGdlbmVzICh3aGljaCBoYXZlIGJlZW4gaW5zZXJ0ZWQvbWFuaXB1bGF0ZWQgaW4gQUxMIE1UIGdlbmVzKS4gKFRoZSBFbnNlbWJsIGRhdGFiYXNlIGlzIHVzZWQgdG8gZmluZCB0aGUgTVQgZ2VuZXMgaW4gdGhlIHNwZWNpZXMhKQogIAojIyMjIyBSZXN1bHRzOiAjIyMjIwoKKiBCYXJwbG90czoKICAtIFJlcHJlc2VudGluZyB0aGUgZGlzdHJpYnV0aW9uIGFuZCBudW1iZXIgb2YgZ2VuZSBjb3VudHMsIHRyYW5zY3JpcHQgY291bnRzLCBhbmQgcGVyY2VudGFnZSBvZiBNVCByZWFkcyBwZXIgY2VsbC4gR2VuZXJhbGx5LCBoaWdoIGZyYWN0aW9uIG9mIE1UIHJlYWRzIGluIGNvbWJpbmF0aW9uIHdpdGggbG93IGdlbmUvdHJhbnNjcmlwdCBjb3VudHMgaW5kaWNhdGUgc3RyZXNzZWQgb3IgZGVhZCBjZWxscy4gSG93ZXZlciwgaGlnaGx5IHByb2xpZmljIHN0ZW0gb3IgY2FuY2VyLWxpa2UgY2VsbCBhcmUgb2Z0ZW4gcmljaCBpbiBNVHMsIHdoZXJlYXMgc29tZSBpbW11bmUgY2VsbHMgc3VjaCBhcyBuZXV0cm9waGlsZXMgYXJlIGluIGxvd2VyIGVuZCBvZiB0aGUgc3BlY3RydW0gaW4gdGVybXMgb2YgZ2VuZSBhbmQgdHJhbnNjcmlwdCBjb3VudHMuIAogIC0gVGhlIGRhc2hlZCByZWQgYW5kIG9yYW5nZSBsaW5lcyByZXByZXNlbnQgdGhlIHRoZW9yZXRpY2FsIHRocmVzaG9sZHMgKFJlZDogMTAlIE1ULCAyMDAgbkdlbmVzLCA1NTAgblVVTUlzLiBPcmFuZ2U6IDcuNSUgTVQpCmBgYHtyIFFDIE1ULCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBwbG90cyBoaXN0b2dyYW1zIHdpdGggdGhlIGZyZXF1ZW5jeSAoY2VsbHMpIGFzIGEgZnVuY3Rpb24gb2YgbkdlbmVzLCBuVU1JcyBhbmQgTVQgcGVyY2VudGFnZQojIC8vIEEgc2VwYXJhdGUgZnVuY3Rpb25zIGNhbGN1bGF0ZXMgYW5kIGFkZHMgdGhlIHBlcmNlbnQgTVQgdG8gdGhlIG9iamVjdCBNZXRhZGF0YQojIC8vIEZvciBlYWNoIGhpc3RvZ3JhbSBsaW5lcyBpbiBlaXRoZXIgcmVkLCBvcmFuZ2UgYW5kIGdyZWVuIHJlcHJlc2VudCB0aGUgdGhyZXNob2xkcyAKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBwZXJjZW50YWdlIG9mIG1pdG9jaG9uZHJpYWwgZ2VuZXMgcGVyIG9iamVjdCBhbmQgYWRkcyBpdCB0byB0aGUgTWV0YURhdGEgc2xvdCAob2JqQG1ldGFkYXRhKQojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBvYmplY3RzCmdldF9NVF9wZXJjZW50YWdlIDwtIGZ1bmN0aW9uKHNvYmopIHsKICAgaWYgKGdyZXBsKCJtdC0iLCBNVF9nZW5lc1sxXSkgPT0gVFJVRSkgewogICBzb2JqW1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChzb2JqLCBwYXR0ZXJuID0gIm10LSIpICMgc2VhcmNoIGZvciAtbXQgcGFzdGVybiBpZiBsb3dlciBjYXNlIAogfSBlbHNlIHsgc29ialtbInBlcmNlbnQubXQiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc29iaiwgcGF0dGVybiA9ICJNVC0iKQogfQogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSB0aGUgZnVuY3Rpb24gZ2V0X01UX3BlcmNlbnRhZ2UKc29ial9saXN0IDwtIHNhcHBseShzb2JqX2xpc3QsIGdldF9NVF9wZXJjZW50YWdlKQoKIyB2aXN1YWxpemUgTVQgcGVyY2VudGFnZSBpbiBjZWxscwpnZXRfaGlzdG9ncmFtc19RQyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgICAgICMgdmlzdWFsaXplIHBlcmNlbnRhZ2UgTVQgZ2VuZXMgcGVyIGNlbGwKICAgICAgaDEgPC0gaGlzdChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10LCBicmVha3MgPSAzMCwgeGxhYiA9ICJQZXJjZW50YWdlIE1pdG9jaG9uZHJpYWwgR2VuZXMgKCUpIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJIaXN0b2dyYW06IFFDIE1UIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCAKICAgICAgICAgICAgIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKSAKICAgICAgYWJsaW5lKHYgPSAxMCwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpCiAgICAgIGFibGluZSh2ID0gNy41LCBjb2w9Im9yYW5nZSIsIGx3ZD0zLCBsdHk9MikKICAgICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIGdlbmVzIGluIGNlbGxzCiAgICAgIGgyIDwtIGhpc3Qoc29ialtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEsIGJyZWFrcyA9IDMwLCB4bGFiID0gIk51bWJlciBvZiBnZW5lcyIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKICAgICAgICAgICAgIG1haW4gPSBwYXN0ZSgiSGlzdG9ncmFtOiBRQyBudW1iZXIgb2YgZ2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICAgIGFibGluZSh2ID0gMjAwLCBjb2w9InJlZCIsIGx3ZD0zLCBsdHk9MikKICAgICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIFVNSXMgKG1vbGVjdWxlcykgaW4gY2VsbHMKICAgICAgaDMgPC0gaGlzdChzb2JqW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BLCBicmVha3MgPSAzMCwgeGxhYiA9ICJOdW1iZXIgb2YgVU1JcyAoUk5BIG1vbGVjdWxlcykiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgbnVtYmVyIG9mIFVNSXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICAgIGFibGluZSh2ID0gNTAwLCBjb2w9InJlZCIsIGx3ZD0zLCBsdHk9MikKICAgICAgcmV0dXJuKCkKfQojIEV4ZWN1dGUgZ2V0X2hpc3RvZ3JhbXNfUUMgZnVuY3Rpb24KaGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBnZXRfaGlzdG9ncmFtc19RQykKCgojIyMjIyMjIyMjIyMgU0VDT05EIFdBWSBUTyBETyBJVCwgRk9SIFNBVklORyBJTUFHRVMgIyMjIyMjIyMjIyMjIyMKI2ZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc29ial9saXN0KSkgewogICMgdmlzdWFsaXplIHBlcmNlbnRhZ2UgTVQgZ2VuZXMgcGVyIGNlbGwKIyAgaDEgPC0gaGlzdChzb2JqX2xpc3RbW2ldXVtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCwgYnJlYWtzID0gMzAsIHhsYWIgPSAiUGVyY2VudGFnZSBNaXRvY2hvbmRyaWFsIEdlbmVzICglKSIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKIyAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgTVQiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCBjb2wgPSAid2hpdGUiLCBsYWJlbHMgPSBUUlVFLCBwbG90ID0gVFJVRSkgCiAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIGdlbmVzIGluIGNlbGxzCiMgIGgyIDwtIGhpc3Qoc29ial9saXN0W1tpXV1bWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BLCBicmVha3MgPSAzMCwgeGxhYiA9ICJOdW1iZXIgb2YgZ2VuZXMiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiMgICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJIaXN0b2dyYW06IFFDIG51bWJlciBvZiBnZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKQogICMgdmlzdWFsaXplIG51bWJlciBvZiBVTUlzIChtb2xlY3VsZXMpIGluIGNlbGxzCiMgIGgzIDwtIGhpc3Qoc29ial9saXN0W1tpXV1bWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEsIGJyZWFrcyA9IDMwLCB4bGFiID0gIk51bWJlciBvZiBVTUlzIChSTkEgbW9sZWN1bGVzKSIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKIyAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgbnVtYmVyIG9mIGdlbmVzIiwgc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSwgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpIAojICBwcmludChoMSkgIyBTQVZFIElUIEZPUiBQSVBFTElORQojICBwcmludChoMSkKIyAgcHJpbnQoaDEpCiN9CgoKCgoKIyMjIyMjIyMgVEVTVElORyBDT0RFCgoKCgoKICAgICAgCmBgYAoKIyMjIyBIZXJlIHdlIHdpbGwgdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgbkdlbmVzIGFuZCBuVU1JcyBhbmQgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGNlbGxzOiAjIyMjCgojIyMjIyBEZXNjcmlwdGlvbjogIyMjIyMKCiogVGVybWlub2xvZ3k6CiAgLSBuRmVhdHVyZV9STkEgaXMgdGhlIG51bWJlciBvZiBnZW5lcyBkZXRlY3RlZCBpbiBlYWNoIGNlbGwgKHZpb2xpbiBwbG90KS4KICAtIG5Db3VudF9STkEgaXMgdGhlIHRvdGFsIG51bWJlciBvZiBtb2xlY3VsZXMgZGV0ZWN0ZWQgd2l0aGluIGEgY2VsbCAoVU1JcykgKHZpb2xpbiBwbG90KS4KICAtIHBlcmNlbnQubXQgaXMgdGhlIHBlcmNlbnRhZ2Ugb2YgbWl0b2Nob25kcmlhbCBVTUlzIHdpdGhpbiBhIGNlbGwgKHZpb2xpbiBwbG90KS4KICAtIENlbGwgY29tcGxleGl0eWlzIHRoZSBwcm9wb3J0aW9uIG9mIG5HZW5lcyByYWx0aXZlIHRvIHRoZSBudW1iZXIgb2YgdHJhbnNjcmlwdHMgKFJOQS1tb2xlY3VsZXMvVU1JcykuCiAgLSBMb3cgY29tcGxleGl0eSBjZWxscyBpcyBhIGNlbGwgdGhhdCBoYXMgZmV3IGdlbmVzLCBidXQgbW9yZSB0cmFuc2NyaXB0cy4KICAtIEhpZ2ggY29tcGxleGl0eSBjZWxscyBpcyBhIGNlbGwgdGhhdCBtb3JlIGdlbmVzIGFuZCBsZXNzIHRyYW5zY3JpcHRzLgogIC0gRG9taW5hbnQgZ2VuZSBpcyBhIGdlbmUgdGhhdCBoYXMgdGhlIGhpaWdoZXN0IGV4cHJlc3Npb24gaW4gYSBjZWxsIHJlbGF0aXZlIHRvIHRoZSBvdGhlciBnZW5lcy4KCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIFZpb2xpbiBwbG90czoKICAtIExvdyBuRmVhdHVyZV9STkEgZm9yIGEgY2VsbCBpbmRpY2F0ZXMgdGhhdCBpdCBtYXkgYmUgZGVhZC9keWluZyBvciBhbiBlbXB0eSBkcm9wbGV0LiBJdCBpcyB1c3VhbGx5IGFjY2VwdGVkIHRoYXQgY2VsbHMgdGhhdCBhcmUgcG9vciBxdWFsaXR5IGFyZSBsaWtlbHkgdG8gaGF2ZSBsb3cgZ2VuZXMgYW5kIFVNSXMgcGVyIGNlbGwsIGFuZCBjb3JyZXNwb25kIHRvIHRoZSBkYXRhIHBvaW50cyBpbiB0aGUgYm90dG9tIGxlZnQgcXVhZHJhbnQgb2YgdGhlIHBsb3QuIEdvb2QgY2VsbHMgd2lsbCBnZW5lcmFsbHkgZXhoaWJpdCBib3RoIGhpZ2hlciBudW1iZXIgb2YgZ2VuZXMgcGVyIGNlbGwgYW5kIGhpZ2hlciBudW1iZXJzIG9mIFVNSXMuIEJ1dCBiZSBjYXJlZnVsIGhlcmUsIHNvbWUgY2VsbCB0eXBlcyBhcmUga25vd24gdG8gaGF2ZSBsb3cgZ2VuZXMgYW5kIFVNSXMuCiAgLSBIaWdoIG5Db3VudF9STkEgYW5kL29yIG5GZWF0dXJlX1JOQSBpbmRpY2F0ZXMgdGhhdCB0aGUgImNlbGwiIG1heSBpbiBmYWN0IGJlIGEgZG91YmxldCAob3IgbXVsdGlwbGV0KS4gQnV0IGJlIGNhcmVmdWwgYWdhaW4sIHNvbWUgY2VsbCB0eXBlcyBhcmUga25vd24gdG8gaGF2ZSBzdXBlciBoaWdoIGdlbmVzIGFuZCBVTUlzIChpLmUuIGRldmVsb3BpbmcgY2VsbHMsIGNhbmNlciwgc3RlbS1jZWxscykuCiAgCiogUGVyY2VudC1NVCB2cyBuR2VuZSAvIFBlcmNlbnQtTVQgdnMgblVNSSBwbG90OiAKICAtIEFnYWluLCBmb3IgYmFkIGNlbGwgd2UgZXhwZWN0IHRvIHNlZSB0aGUgaGlnaCBwZXJjZW50YWdlIE1UIHdpdGggbG93IG51bWJlciBvZiBnZW5lcy9VTUlzICh1bmxlc3MgZXhwZWN0ZWQgb3RoZXJ3aXNlLCBlLmcuIGNhcmRpYWMgY2VsbHMpLgogIC0gVGhlIGRhc2hlZCByZWFkIGxpbmUgcmVwcmVzZW50cyBhIHRoZW9yZXRpY2FsIE1UIGxpbWl0IG9mIDEwJSBhbmQgb3JhbmdlIDUlLgoKKiBuVU1JcyB2cyBuR2VuZXMgcGxvdCAoYWxzbyBsb2cgc2NhbGVkIHZlcnNpb24pOiAKICAtIEVtcHR5IGRyb3BsZXRzIGFuZCBsb3cgcXVhbGl0eSBjZWxscyBvZnRlbiBoYXZlIHZlcnkgZmV3IGdlbmVzIGFuZCBtYW55ICIwIiBnZW5lcy9VTUkgY291bnRzIChNaW5pbXVtIG9mIDUwMCBVTUlzIGlmIHlvdSB1c2UgdGhlIGZpbHRlcmVkIGNvdW50cyBtYXRyaXgpLgogIC0gQ2VsbCBtdWx0aXBsZXRzIChkb3VibGV0cykgb2Z0ZW4gaGF2ZSB2ZXJ5IGhpZ2ggZ2VuZS9VTUkgY291bnQuCiAgLSBOb3RpY2UgdGhhdCBjZWxsIHdpdGggdGhlIGhpZ2hlc3QgbWl0b2Nob25kcmlhbCBnZW5lcyBhcmUgbG9jYXRlZCBpbiB0aGUgYm90dG9tLWxlZnQgb2YgdGhlIHBsb3QsIGluZGljYXRpbmcgdGhhdCB0aGVzZSBhcmUgdHJ1bHkgYmFkIGNlbGwgY29uc2lkZXJpbmcgdGhleSBjb250YWluIGhpZ2ggTVQgcGVyY2VudGFnZSwgYnV0IGxvdyBudW1iZXIgb2YgZ2VuZXMvVU1Jcy4gS2VlcCBpbiBtaW5kIHRoYXQgZ29vZCBjZWxscyBjb3VsZCBhbHNvIGhhdmUgbnVtYmVyIG9mIE1UIGdlbmVzLCB0aGVzZSBjZWxscyBhcmUgb2Z0ZW4gYWN0aXZhdGVkIGNlbGxzIChpLmUuIFN0ZW0vY2FuY2VyL2N5Y2xpbmcvZGV2ZWxvcGluZyBjZWxscykuIE5vdyBpdCBjb3VsZCBhIGxpdHRsZSB0cm91YmxpbmcgaWYgdGhlIG1ham9yaXR5IG9mIHlvdXIgaGlnaCBNVCBjZWxscyBhbHNvIGNvbnRhaW4gbWFueSBnZW5lcy9VTUlzLCBlc3BlY2lhbGx5IGlmIHlvdSBkbyBub3QgZXhwZWN0IGFjdGl2YXRlZCBjZWxsIHR5cGVzIGluIHlvdXIgZGF0YS4gWW91IGhhdmUgdG8gYmUgYXdhcmUgd2l0aCB0aGUgdHlwZSBvZiBjZWxsIHlvdSBhcmUgd29ya2luZyB3aXRoLgogIC0gSW4gdGhlIG5VTUkgdnMgbkdlbmVzIHBsb3Qgd2UgY2FuIGFsc28gc2VlIHRoZSBjb21wbGV4aXR5IG9mIHRoZSBkYXRhc2V0IHdpdGggcG90ZW50aWFsIGVycm9ycy4gR2VuZXJhbGx5LCB3ZSBleHBlY3QgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIG51bWJlciBvZiBnZW5lcyBhbmQgVU1JcyBpbiB0aGlzIHBsb3QuIElmIGNlbGxzIGluIHRoZSBwbG90IGFyZSBza2V3ZWQgZmFyIGZyb20gdGhlIG1pZGRsZSBsaW5lIHRvd2FyZHMgdGhlIGJvdHRvbS1yaWdodCB0aGlzIGNvdWxkIG1lYW4gdGhhdCB0aGUgZXhwZXJpbWVudCBoYXMgY2FwdHVyZWQgdmVyeSBmZXcgbnVtYmVyIG9mIGdlbmVzIGFuZCB0aG9zZSBzYW1lIGdlbmVzIGhhdmUgYmVlbiBzZXF1ZW5jZWQgbXVsdGlwbGUgdGltZXMuIFNpbWlsYXJseSwgaWYgdGhlIGNlbGxzIGFyZSBza2V3ZWQgdG93YXJkcyB0aGUgdG9wLWxlZnQgdGhpcyBjb3VsZCBtZWFuIHRoYXQgZXhwZXJpbWVudCBoYXMgY2FwdHVyZWQgbWFueSBnZW5lcywgYnV0IHRoZXkgYXJlIG5vdCBzZXF1ZW5jZWQgZGVlcGx5IGVub3VnaCAod2hpY2ggcmVzdWx0cyBpbiBsb3cgbnVtYmVyIG9mIFVNSXMpLiBLZWVwIGluIG1pbmQgdGhhdCBhcyBhIHJlc3VsdCBvZiBSTkEgZGVncmFkYXRpb24sIGEgZmFpbGVkIGV4cGVyaW1lbnQgY291bGQgc3RpbGwgZ2l2ZSB1cyBhIGdvb2QgcGxvdHMuCiAgLSBUaGUgb3JhbmdlIGRhc2hlZCBsaW5lcyBzaG93IHRoZSB0aGVvcmV0aWNhbCBsb3dlciBsaW1pdHMgb2YgVU1JcyAoNTUwKSBhbmQgZ2VuZXMgKDIwMCkuIFRoZSB5ZWxsb3cgZGFzaGVkIGxpbmVzIHNob3cgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFudGlsZXMgb2YgYm90aCBudW1iZXIgb2YgZ2VuZXMgYW5kIFVNSXMgKGRlZmF1bHQgc2V0IGJldHdlZW4gMi05OCUpLiBJZiB5b3UgY2hvb3NlIGZpbHRlciB0aGUgbnVtYmVyIG9mIGdlbmVzIGFuZCBVTUlzIGJ5IHVzZXItZGVmaW5lZCBxdWFudGlsZXMsIHRoZW4gdGhlIHllbGxvdyBkYXNoZWQgbGluZXMgd2lsbCBiZSBzZXQgYXQgdGhvc2UgbnVtYmVycy4KICAKKiBDb21wbGV4aXR5IHBsb3QgKHRoZSBzaW5ndWxhciBwbG90IGJlbG93KTogCiAgLSBDb21wbGV4aXR5IGNhbiBhbHNvIGJlIHZpc3VhbGl6ZWQgYnkgZGl2aWRpbmcgdGhlIG5HZW5lcyBieSBuVU1JcyBmb3IgZWFjaCBjZWxsLiBIaWdoZXIgdmFsdWVzIGluZGljYXRlIHRoYXQgd2UgYXJlIGdldHRpbmcgc2hhbGxvd2VyIGNvdmVyYWdlIG9mIG1vcmUgZ2VuZXMsIGFuZCBsb3dlciB2YWx1ZXMgbWVhbiB0aGF0IHdlIGFyZSBzZWVpbmcgZmV3ZXIgZ2VuZXMgb3ZlcmFsbC4gCiAgLSBHZW5lcmFsbHksIHdlIGV4cGVjdCB0aGUgbm92ZWx0eSBzY29yZSB0byBiZSBhYm92ZSAwLjgwIChpbmRpY2F0ZWQgd2l0aCBkYXNoZWQgcmVkIGxpbmUpLgogIC0gQXMgdGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIG51bWJlciBvZiBnZW5lcyBhbmQgdHJhbnNjcmlwdHMgZm9yIHRoZSBtYWpvcml0eSBvZiB0aGUgY2VsbHMsIGl0IGlzIGV4cGVjdGVkIHRvIGZpbmQgdGhlIGhpZ2hlc3QgcHJvYmFiaWxpdHkgYXQgYSBnZW5lcy90cmFuc2NyaXB0IHJhdGlvIGJldHdlZW4gMC44NS0wLjk1LCBldmVuIGZvciBsb3ctY29tcGxleGl0eSBjZWxscy4gQSBsYXJnZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IGFueXRoaW5nIGJlbG93IDAuOCBpbmRpY2F0ZXMgYSBmYWlsZWQgZXhwZXJpbWVudCwgYXMgaW5zdWZmaWNpZW50IGdlbmVzIGhhdmUgYmVlbiBjYXB0dXJlZCBpbiBwcm9wb3J0aW9uIHRvIHRyYW5zY3JpcHQgY291bnRzLgogIAoqIFBsb3R0aW5nIGNvbXBsZXhpdHkgYXMgZnVuY3Rpb24gb2YgcGVyY2VudGFnZSBvZiBjb3VudHMgcGVyIGdlbmUgKHRoZSBmaXJzdCB0cmlvIHBsb3RzIGJlbG93KToKICAtIENvbXBsZXhpdHk6IExvZzEwIC0gblVNSXMgdnMgbkdlbmVzOiAgICBBZ2FpbiwgbWFrZSBhbm90aGVyIHBsb3QgYXMgYmVmb3JlIChsb2cxMCAtIG5VTUlzIHZzIG5HZW5lcyBwbG90KSwgYnV0IG5vdyB3ZSBmaXQgYSBsaW5lYXIgbW9kZWwgYW5kIGNhbGN1bGF0ZSB0aGUgcmVzaWR1YWwgZnJvbSB0aGUgbWlkZGxlIHBvaW50IGZvciBlYWNoIGNlbGwuIE5vdyB3ZSBjYW4gY2xlYXJseSB2aXN1YWxpemUgd2hpY2ggY2VsbHMgaGF2ZSBtb3JlIHRyYW5zY3JpcHRzIHZzIGdlbmVzIHJlbGF0aXZlIHRvIHRoZSBtaWRkbGUtbGluZSAob3IgdmljZSB2ZXJzYSkuIFRoaXMgaXMgaW5kaWNhdGVkIGJ5IHRoZSBzdHJlbmd0aCBvZiB0aGUgYmx1ZSBvciByZWQgY29sb3IuCiAgLSBSZXNpZHVhbCB2cyBEZW5zaXR5OiAgICBJbiB0aGlzIHBsb3QsIHdlIGNhbiBzZWUgdGhlIGZyZXF1ZW5jeSAoZGVuc2l0eSkgb2YgY2VsbHMgYXMgYSBmdW5jdGlvbiBpcyB0aGUgcmVzaWR1YWxzIChpLmUuIGRldmlhdGlvbiBmcm9tIHRoZSBsaW5lYXIgcmVncmVzc2lvbikuIFdoYXQgZG8geW91IHNlZSBoZXJlPyBBIG5vcm1hbCBkaXN0cmlidXRpb24gb3Igc2tld2VkIHRvd2FyZHMgdGhlIGxlZnQgb3IgcmlnaHQ/IFRoaXMgZGVuc2l0eSBwbG90IGlzIHNpbXBseSBhbiBhZGRpdGlvbiB0byB0aGUgbGluZWFyIG1vZGVsIGFuZCBpdCBpcyBleHBlY3RlZCB0aGF0IHlvdSBmaW5kIHRoZSBsYXJnZXN0IGRlbnNpdHkgYXJvdW5kIDAsIG1lYW5pbmcgdGhhdCB0aGUgbWFqb3JpdHkgb2YgdGhlIGNlbGxzIHdlcmUgaW5kZWVkIGNsb3NlIHRvIHRoZSBtaWRkbGUgbGluZSBpbiB0aGUgbGluZWFyIHJlZ3Jlc3Npb24uIEp1c3QgbGlrZSBiZWZvcmUsIGlmIHRoZSBncmFwaHMgaXMgc2tld2VkIHRvd2FyZCB0aGUgbGVmdCAobmVnYXRpdmUgcmVzaWR1YWxzKSwgdGhpcyBtZWFucyB0aGF0IHlvdSBtYXkgaGF2ZSBhbiB1bmRlc2lyZWQgbnVtYmVyIG9mIGxvdy1jb21wbGV4aXR5IGNlbGxzLiBMaWtld2lzZSwgaWYgdGhlIGdyYXBoIGlzIHNrZXdlZCB0b3dhcmRzIHRoZSByaWdodCBzaWRlIChwb3NpdGl2ZSByZXNpZHVhbHMpLCB0aGVuIHlvdSBtYXkgbWFueSBoaWdoLWNvbXBsZXhpdHkgY2VsbHMuIFVzdWFsbHksIHN1Y2ggYmVoYXZpb3IgaXMgcmVsYXRlZCB0byBzb21lIHNvcnQgb2YgZmFpbGVkIGV4cGVyaW1lbnQuCiAgLSBSZXNpZHVhbCB2cyBQZXJjZW50YWdlIExhcmdlc3QgZ2VuZXM6ICAgSW4gdGhpcyBwbG90LCBmb3IgZWFjaCBjZWxsLCB3ZSBjYWxjdWxhdGUgdGhlIGdlbmUgd2l0aCB0aGUgaGlnaGVzdCBwZXJjZW50YWdlIG9mIHJlYWRzIGFuZCBwdXQgYWdhaW5zdCB0aGUgcmVzaWR1YWxzLiBZb3UgY2FuIG5vdyBzZWUgYSBzZW1pLWRlbnNpdHkgcGxvdCBhcyBiZWZvcmUsIGJ1dCBub3cgd2l0aCB0aGUgYWN0dWFsIGNlbGxzLiBEbyB5b3Ugc2VlIGEgcGF0dGVybiBoZXJlPyBEbyB5b3Ugc2VlIGFueSBsb3ctY29tcGxleGl0eSBjZWxscyB3aXRoIGEgaGlnaCBwZXJjZW50YWdlIG9mIGEgZG9taW5hbnQgZ2VuZT8gSWRlYWxseSwgd2UgZXhwZWN0IGEgdm9sY2FubyBwbG90IGNlbnRlcmVkIGFyb3VuZCB0aGUgbWlkZGxlLiBJZiB5b3UgaGF2ZSBtYW55IGxvdy1jb21wbGV4aXR5IGNlbGxzIHdpdGggYSBzaWduaWZpY2FudGx5IGluZmxhdGVkIGRvbWluYW50IGdlbmUsIHRoaXMgbWlnaHQgaW5kaWNhdGUgYmFkIGNlbGxzLiBCdXQgZmlyc3QsIHdlIGhhdmUgdG8gZmluZCBvdXQgd2luY2ggZG9taW5hbnQgZ2VuZSB0aGV5IGV4cHJlc3MgdG8gbWFrZSBhIGZpbmFsIGNvbmNsdXNpb24gaWYgaXQgaXMgdHJ1bHkgcmVsYXRlZCB0byBzb21lIGJpb2xvZ2ljYWwgcmVhc29uIG9yIHRlY2huaWNhbC4KCiogUGxvdHRpbmcgY29tcGxleGl0eSBhbmQgZXhhbWluaW5nIGRvbWluYW50IGdlbmVzICh0aGUgZmluYWwgdHJpbyBwbG90cyBiZWxvdyk6CiAgLSBDb21wbGV4aXR5IGJ5IExhcmdlc3QgR2VuZTogICBUaGlzIGlzIHRoZSBzYW1lIGxpbmVhciBwbG90IGFzIGJlZm9yZSwgYnV0IG5vdyB3ZSB2aXN1YWxpemUgdGhlIG1vc3QgZG9taW5hbnQgZ2VuZSBwZXIgY2VsbCAodG9wIDggb3V0IG9mIHRvdGFsIGluIHRoZSBkYXRhc2V0KS4gRG8geW91IHNlZSBhIHBhdHRlcm4gaGVyZSBvciBhIHNwZWNpZmljIGdlbmUgdGhhdCBpcyBleHByZXNzZWQgaW4gbG93IG9yIGhpZ2ggY29tcGxleGl0eSBjZWxscz8gT2Z0ZW4sIHRoZSB1bnVzdWFsIHBvcHVsYXRpb25zIGluIHRoZXNlIHBsb3RzIGNhbiBkZXJpdmUgZnJvbSB0aGUgYWN0aXZpdHkgb2YgYSBzaW5nbGUgZ2VuZSwgc28gbm93IHlvdSBoYXZlIGEgY2hhbmNlIGZpZ3VyZSB0aGlzIG91dC4uLiBJZiB0aGVzZSBnZW5lcyBoYXBwZW4gdG8gYmUgZnJvbSBhIG1pdG9jaG9uZHJpYWwgb3JpZ2luLCB0aGVuIHlvdSBhcmUgbGlrZWx5IGRlYWxpbmcgd2l0aCBkZWFkIGNlbGxzLiBMaWtld2lzZSwgaGlnaCBleHByZXNzaW9uIG9mIE1BTEFUMSBjYW4gYWxzbyBpbmRpY2F0ZSBkZWFkIGNlbGxzLgogIC0gUmVzaWR1YWxzIHZzIFBlcmNlbnRhZ2UgTGFyZ2VzdCBHZW5lczogICAgU2FtZSBhcyBiZWZvcmUsIGJ1dCBub3cgd2l0aCB0aGUgZG9taW5hbnQgZ2VuZSB2aXN1YWxpemVkLiBXaGljaCBnZW5lcyBhcmUgdGhlIGRvbWluYW50IG9uZXMgaW4geW91IG9mZiB0YXJnZXQgcG9wdWxhdGlvbnM/IEFuZCBkb2VzIHRoaXMgbWVldCB5b3VyIGV4cGVjdGF0aW9uPyAgCiAgLSBSZXNpZHVhbHMgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzICsgTVQgJTogICBTYW1lIHBsb3QsIGJ1dCBub3cgd2l0aCBwZXJjZW50YWdlIE1ULiBEbyB0aGUgb2ZmLXRhcmdldCBjZWxsIHBvcHVsYXRpb25zIHNob3cgaGlnaCBwZXJjZW50YWdlIG9mIE1UPyBBbmQgZG8gZmluZCBzb21lIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhpcyBwbG90IGFuZCB0aGUgZG9taW5hbnQgZ2VuZXMgZnJvbSBiZWZvcmUgKE1UIGdlbmVzKT8KYGBge3IgUUMgZ3JhcGggYW5kIGZpbHRlcmluZywgZmlnLmhlaWdodD05LCBmaWcud2lkdGg9MTcsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcGxvdHMgVmlvbGluIHBsb3Qgd2l0aCB0aGUgZnJlcXVlbmN5IChjZWxscykgYXMgYSBmdW5jdGlvbiBvZiBuR2VuZXMsIG5VTUlzIGFuZCBNVCBwZXJjZW50YWdlCiMgLy8gVGhpcyBjaHVuayBwbG90cyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBvZiBuR2VuZXMgYXMgYSBmdW5jdGlvbiBvZiBuVU1JcyAoYWxzbyBMb2cgc2NhbGVkKSB3aXRoIE1UIHBlcmNlbnRhZ2UgcGVyIGNlbGwKIyAvLyBUaGlzIGNodW5rIHBsb3RzIENvbXBsZXhpdHkgKERlbnNpdHkgdnMgbG9nKGdlbmVzIHBlciBVTUkpKQojIC8vIFRoaXMgY2h1bmsgRmVhdHVyZSBTY2F0dGVycyBjZWxscyB3aXRoIHBlcmNlbnQgTVQgYXMgYSBmdW5jdGlvbiBvZiBuR2VuZXMgYW5kIG5VTUlzCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB2aW9saW4gcGxvdHMgb2YgIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiIGZvciBlYWNoIG9iamVjdAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBzY2F0dGVycGxvdHMgb2YgIm5VTUlzIHZzIG5HZW5lcyIsICJQZXJjZW50LU1UIHZzIG5HZW5lcyIsICJQZXJjZW50LU1UIHZzIG5VTUlzIiBmb3IgZWFjaCBvYmplY3QKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKZ2V0X3Zpb2xfUUMgPC0gZnVuY3Rpb24oc29iaikgewogIHYxIDwtIFZsblBsb3Qoc29iaiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzLCBjb2xzID0gIm1hZ2VudGEiKQogIHByaW50KHYxKSAjIFNBVkUgSVQgRk9SIFBJUEUKICAKICBhc190aWJibGUoc29ialtbXV0sIHJvd25hbWVzPSJDZWxsLkJhcmNvZGUiKSAtPiBxYy5tZXRyaWNzICMgc29ial9saXN0W1sxXV1bW11dIHNob3dzIGRhdGEuZnJhbWUgb2YgbWV0YWRhdGEKCiAgcDEgPC0gcWMubWV0cmljcyAlPiUKICAgIGFycmFuZ2UocGVyY2VudC5tdCkgJT4lCiAgICBnZ3Bsb3QoYWVzKG5Db3VudF9STkEsbkZlYXR1cmVfUk5BLCBjb2xvdXI9cGVyY2VudC5tdCkpICsgCiAgICBnZW9tX3BvaW50KCkgKyAKICAgIHNjYWxlX2NvbG91cl9ncmFkaWVudG4oY29sb3VycyA9IGMoJ2JsYWNrJywgJ3JlZDMnLCAncmVkMicpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDYpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5oaWdoID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPD0gMSAmIGlzLm5hKGZlYXR1cmUucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IGZlYXR1cmUucXVhbnRpbGUuaGlnaH1lbHNle2ZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IDAuOTh9KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUubG93ID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5sb3cpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IGZlYXR1cmUucXVhbnRpbGUubG93fWVsc2V7ZmVhdHVyZS5xdWFudGlsZS5sb3cgPSAwLjAyfSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNTUwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmhpZ2ggPj0gMCAmIFVNSS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5oaWdoID0gVU1JLnF1YW50aWxlLmhpZ2h9ZWxzZXtVTUkucXVhbnRpbGUuaGlnaCA9IDAuOTh9KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5sb3cgPj0gMCAmIFVNSS5xdWFudGlsZS5sb3cgPD0gMSAmIGlzLm5hKFVNSS5xdWFudGlsZS5sb3cpID09IEZBTFNFKXtVTUkucXVhbnRpbGUubG93ID0gVU1JLnF1YW50aWxlLmxvd31lbHNle1VNSS5xdWFudGlsZS5sb3cgPSAwLjAyfSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiZ3JlZW4iLCBzaXplPTEpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJuVU1JcyB2cyBuR2VuZXMgd2l0aCBwZXJjZW50IE1UIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgCiAgICB0aGVtZV9idygpICsgIyBtYWtlIGZpbGxlciB3aGl0ZQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgIyByZW1vdmUgcmFzdGVyCiAgCiAgcDEuMSA8LSBxYy5tZXRyaWNzICU+JQogICAgYXJyYW5nZShwZXJjZW50Lm10KSAlPiUKICAgIGdncGxvdChhZXMobG9nMTAobkNvdW50X1JOQSksbG9nMTAobkZlYXR1cmVfUk5BKSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdyZWQzJywgJ3JlZCcpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDYpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKDIwMCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAocXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSBmZWF0dXJlLnF1YW50aWxlLmhpZ2h9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5sb3cgPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtVTUkucXVhbnRpbGUuaGlnaCA9IFVNSS5xdWFudGlsZS5oaWdofWVsc2V7VU1JLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5sb3cgPSBVTUkucXVhbnRpbGUubG93fWVsc2V7VU1JLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiZ3JlZW4iLCBzaXplPTEpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJMb2cxMCBzY2FsZWQ6IG5VTUlzIHZzIG5HZW5lcyB3aXRoIHBlcmNlbnQgTVQiKSkgKyAKICAgIHlsYWIoIkxvZzEwIChOdW1iZXIgb2YgR2VuZXMpIikgKyAKICAgIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogICAgdGhlbWVfYncoKSArICMgbWFrZSBmaWxsZXIgd2hpdGUKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICAjIHJlbW92ZSByYXN0ZXIKICAKICAjIEFkZCBudW1iZXIgb2YgZ2VuZXMgcGVyIFVNSSBmb3IgZWFjaCBjZWxsIHRvIG1ldGFkYXRhCiAgc29iaiRsb2cxMEdlbmVzUGVyVU1JIDwtIGxvZzEwKHNvYmokbkZlYXR1cmVfUk5BKSAvIGxvZzEwKHNvYmokbkNvdW50X1JOQSkKICAjIFZpc3VhbGl6ZSB0aGUgb3ZlcmFsbCBjb21wbGV4aXR5IG9mIHRoZSBnZW5lIGV4cHJlc3Npb24gYnkgdmlzdWFsaXppbmcgdGhlIGdlbmVzIGRldGVjdGVkIHBlciBVTUkKICBwMS4yIDwtIHNvYmpAbWV0YS5kYXRhICU+JQogIAlnZ3Bsb3QoYWVzKGxvZzEwR2VuZXNQZXJVTUkpKSArCiAgCWdlb21fZGVuc2l0eShhbHBoYSA9IDEsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MS41KSArCiAgCXRoZW1lX2NsYXNzaWMoKSArCiAgCWdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuOCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInJlZCIsIHNpemU9MSkgKwogICAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eSBQbG90OiIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgIikpICsgCiAgICB5bGFiKCJEZW5zaXR5IikgKyAKICAgIHhsYWIoIkxvZzEwIEdlbmVzL1VNSSAoR2VuZXMgcGVyIFVNSSkiKQogIAogICAgICMgT0xEIFVNSSB2cyBHZW5lIHBsb3QKIyAgICBwMSA8LSBGZWF0dXJlU2NhdHRlcihzb2JqLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIiAsIGNvbHMgPSAiYmxhY2siLCApICsgCiMgICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKyBnZ3RpdGxlKHBhc3RlKCJuVU1JcyB2cyBuR2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiMgICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKIyAgICB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkKICAKICAKICAjIExldCB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGRhdGEgYW5kIGRyaXZlbiBieSB3aGF0IGdlbmUuIAogICMgQ2FsY3VsYXRlIGNhbGN1bGF0ZSB0aGUgbG9nMTAobkZlYXR1cmVfUk5BKSAvIGxvZzEwKG5Db3VudF9STkEpKSBhbmQgcHV0IGluIHRoZSBxYy5tZXRyaWMKICBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eT1sb2cxMChuRmVhdHVyZV9STkEpIC8gbG9nMTAobkNvdW50X1JOQSkpICAtPiBxYy5tZXRyaWNzCiAgIyBNYWtlIGxpbmVhciBtb2RlbHMgb2YgbG9nMTAobkZlYXV0dXJlcykgdnMgTG9nMTAoblVNSXMpIGFuZCBwdXQgaW4gcHV0IGluIGNvbXBsZXhpdHkubG0KICAjIEhlcmUsIHdlIGNhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBvYnNlcnZlZCB2YWx1ZSB0byB0aGUgZXhwZWN0ZWQKICBsbShsb2cxMChxYy5tZXRyaWNzJG5GZWF0dXJlX1JOQSl+bG9nMTAocWMubWV0cmljcyRuQ291bnRfUk5BKSkgLT4gY29tcGxleGl0eS5sbQogICMgQ2FsY3VsYXRlIHRoZSBjb21wbGV4aXR5IGZyb20gdGhlIG1pZGRsZSBsaW5lIG9mIHRoZSBsaW5lYXIgbW9kZWwKICAjIFdlIHdpbGwgdXNlIHRoaXMgZm9yIHRoZSBjb2xvciBzY2FsZSBvZiB0aGUgZ3JhcGggYXMgd2VsbC4KICBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eV9kaWZmID0gbG9nMTAobkZlYXR1cmVfUk5BKSAtICgobG9nMTAocWMubWV0cmljcyRuQ291bnRfUk5BKSpjb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSkrY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pCiAgKSAtPiBxYy5tZXRyaWNzCiAgIyBGaW5kIHRoZSBkZWx0YSBkaWZmZXJlbmNlIGZvciB0aGUgZ3JhcGgKICBtaW4oYyhtYXgocWMubWV0cmljcyRjb21wbGV4aXR5X2RpZmYpLDAtbWluKHFjLm1ldHJpY3MkY29tcGxleGl0eV9kaWZmKSkpIC0+IGNvbXBsZXhpdHlfc2NhbGUKCiAgIyBIZXJlIHdlIHZpc3VhbGl6ZSB0aGUgdGhlIGRhdGEgY29tcGxleGl0eSAoY2VsbHMpIGJhc2VkIG9uIHRoZSBjYWxjdWxhdGlvbnMgYWJvdmUKICBwMS4zIDwtIHFjLm1ldHJpY3MgJT4lIAogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eV9kaWZmPXJlcGxhY2UoY29tcGxleGl0eV9kaWZmLGNvbXBsZXhpdHlfZGlmZjwgLTAuNSwtMC41KSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxvZzEwKG5Db3VudF9STkEpLCB5PWxvZzEwKG5GZWF0dXJlX1JOQSksIGNvbG91cj1jb21wbGV4aXR5X2RpZmYpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2FibGluZShzbG9wZT1jb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSwgaW50ZXJjZXB0ID0gY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pICsKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdz0iYmx1ZTIiLG1pZD0iZ3JleSIsaGlnaD0icmVkMiIpICsKICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5OiBMb2cxMCAtIG5VTUlzIHZzIG5HZW5lcyIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSkgKyAKICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgeGxhYigiTG9nMTAgKE51bWJlciBvZiBVTUlzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgogICMgSGVyZSB3ZSB2aXN1YWxpemUgdGhlIGRlbnNpdHkgcGxvdCBvZiB0aGUgY2VsbHMgZnJvbSB0aGUgbWlkZGxlIG9mIHRoZSBsaW5lYXIgZ3JhcGggZnJvbSBQMS4zCiAgcDEuNCA8LSBxYy5tZXRyaWNzICU+JSBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmKSkgKyAKICBnZW9tX2RlbnNpdHkoZmlsbD0ieWVsbG93IikgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFsIHZzIERlbnNpdHkiKSkgKyAKICB5bGFiKCJEZW5zaXR5IikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgTm93IGxldHMgd2hpY2ggZ2VuZXMgYXJlIGFjdHVhbGx5IGRyaXZpbmcgdGhlIGxvdyBjb21wbGV4aXR5IGNlbGxzIGluIHRoZSBkYXRhCiAgIyBGb3IgdGhpcywgd2UgZmlyc3QgY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIGxhcmdlc3QgZ2VuZXMuCiAgIyBGaW5kIHRoZSBjZWxscyB3aXRoIGxhcmdlc3QgY291bnRzCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfY291bnQgPSBhcHBseShzb2JqQGFzc2F5cyRSTkFAbGF5ZXJzJGNvdW50cywgMiwgbWF4KSkgLT4gcWMubWV0cmljcyAjICIyIiBpcyB0byByZXR1cm4gbWF4IGNvbHVtbnMgdmFsdWVzCiAgIyBmaW5kIHRoZSBpbmRleCBvZiB0aGUgY2VsbCB3aXRoIGxhcmdlc3QgY291bnRzCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfaW5kZXggPSBhcHBseShzb2JqQGFzc2F5cyRSTkFAbGF5ZXJzJGNvdW50cywgMiwgd2hpY2gubWF4KSkgLT4gcWMubWV0cmljcwogICMgVXNlIHRoZSBpbmRleCBhbmQgZ2V0IHRoZSBnZW5lIG5hbWUgdGhhdCBhY2NvdW50cyBmb3IgdGhlIGxhcmdlc3QgY291bnRzIHBlciBjZWxsCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfZ2VuZSA9IHJvd25hbWVzKHNvYmopW2xhcmdlc3RfaW5kZXhdKSAtPiBxYy5tZXRyaWNzCiAgIyBOb3cgY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIHJlbGF0aXZlIHRvIHRoZSB0b3RhbCBjb3VudHMgaW4gdGhlIGRhdGEKICBxYy5tZXRyaWNzICU+JSBtdXRhdGUocGVyY2VudC5MYXJnZXN0LkdlbmUgPSAgMTAwICogbGFyZ2VzdF9jb3VudCAvIG5Db3VudF9STkEpIC0+IHFjLm1ldHJpY3MKICAKICAjIFZpc3VhbGl6ZSB0aGUgY29tcGxleGl0eSBleHBsYWluZWQgYnkgcGVyY2VudGFnZSBvZiBsYXJnZXN0IGdlbmVzCiAgcDEuNSA8LSBxYy5tZXRyaWNzICU+JSBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lKSkgKyAKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbHMgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzIikpICsgCiAgICB5bGFiKCJQZXJjZW50YWdlIExhcmdlc3QgR2VuZSAoJSkiKSArIAogICAgeGxhYigiQ29tcGxleGl0eSBEaWZmZXJlbmNlIChSZXNpZHVhbHMpIikgKyAKICAgIHRoZW1lX2J3KCkgKyAKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCiAgCiAgIyBTb3J0IHRoZSBwZXJjZW50YWdlIGxhcmdlc3QgZ2VuZXMgCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6Z3JvdXBfYnkobGFyZ2VzdF9nZW5lKSAlPiUgZHBseXI6OmFycmFuZ2UoZGVzYyhwZXJjZW50Lkxhcmdlc3QuR2VuZSkpIC0+IGxhcmdlc3RfZ2VuZV9saXN0CiAgIyBGaWx0ZXIgb3V0IHRoZSBnZW5lcyA+NSUgY291bnRzIAogIGxhcmdlc3RfZ2VuZV9saXN0ICU+JQogIGRwbHlyOjpmaWx0ZXIocGVyY2VudC5MYXJnZXN0LkdlbmUgPiAwLjUpICU+JSAjIGZpbHRlciBleGlzdHMgaW4gb3RoZXIgcGFja2FnZXMsIHVzZSBkcGx5cjo6IHRvIGZpeAogIGRwbHlyOjpwdWxsKGxhcmdlc3RfZ2VuZSkgLT4gbGFyZ2VzdF9nZW5lc190b19wbG90CiAgbGFyZ2VzdF9nZW5lc190b19wbG90IDwtIHVuaXF1ZShsYXJnZXN0X2dlbmVzX3RvX3Bsb3QpWzE6OF0gIyBSZW1vdmUgZHVwbGljYXRlZCBnZW5lIG5hbWVzIGFuZCB0YWtlIHVwIHRvIDEwIGdlbmVzCiAgCiAgIyBQbG90IHRoZSBsaW5lYXIgY29tcGxleGl0eSBtb2RlbCB0aGF0IGV4cGxhaW4gdGhlIGRldmlhdGlvbiBieSB0aGUgbGFyZ2VzdCBnZW5lcwogIHAxLjYgPC0gcWMubWV0cmljcyAlPiUKICBkcGx5cjo6ZmlsdGVyKGxhcmdlc3RfZ2VuZSAlaW4lIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkgJT4lCiAgZHBseXI6Om11dGF0ZShsYXJnZXN0X2dlbmU9ZmFjdG9yKGxhcmdlc3RfZ2VuZSwgbGV2ZWxzPWxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkpICU+JQogIGRwbHlyOjphcnJhbmdlKGxhcmdlc3RfZ2VuZSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxvZzEwKG5Db3VudF9STkEpLCB5PWxvZzEwKG5GZWF0dXJlX1JOQSksIGNvbG91cj1sYXJnZXN0X2dlbmUpKSArCiAgZ2VvbV9wb2ludChzaXplPTEuNSkgKwogIGdlb21fYWJsaW5lKHNsb3BlPWNvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzJdLCBpbnRlcmNlcHQgPSBjb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1sxXSkgKyAjaW1wb3J0IHRoZSBsaW5lIGZvcm0gbGluZWFyIG1vZGVsIGZyb20gYmVmb3JlCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAoMjAwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAocXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSBmZWF0dXJlLnF1YW50aWxlLmhpZ2h9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5sb3cgPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtVTUkucXVhbnRpbGUuaGlnaCA9IFVNSS5xdWFudGlsZS5oaWdofWVsc2V7VU1JLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5sb3cgPSBVTUkucXVhbnRpbGUubG93fWVsc2V7VU1JLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiZ3JleSIsUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksIlNldDEiKSkpICsKICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5IGJ5IExhcmdlc3QgR2VuZSIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSkgKyAKICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgeGxhYigiTG9nMTAgKE51bWJlciBvZiBVTUlzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpIAogICAgCiAgIyBOb3cgcGxvdCBhIHNjYXR0ZXIgb2YgdGhlIGNlbGxzIHdpdGggdGhlIHJlc2lkdWFscyBvbiB0aGUgeC1heGlzIGFuZCBwZXJjZW50YWdlIGxhcmdlc3QgZ2VuZSBpbiB0aGUgeS1heGlzCiAgcDEuNyA8LSBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjpmaWx0ZXIobGFyZ2VzdF9nZW5lICVpbiUgbGFyZ2VzdF9nZW5lc190b19wbG90KSAlPiUKICBkcGx5cjo6bXV0YXRlKGxhcmdlc3RfZ2VuZT1mYWN0b3IobGFyZ2VzdF9nZW5lLCBsZXZlbHM9bGFyZ2VzdF9nZW5lc190b19wbG90KSkgJT4lCiAgZHBseXI6OmFycmFuZ2UobGFyZ2VzdF9nZW5lKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lLCBjb2xvdXI9bGFyZ2VzdF9nZW5lKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0xLjUpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jKCJncmV5IixSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoOSwiU2V0MSIpKSkgKyAKICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbCB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMiKSkgKyAKICB5bGFiKCJQZXJjZW50YWdlIExhcmdlc3QgR2VuZSAoJSkiKSArIAogIHhsYWIoIkNvbXBsZXhpdHkgRGlmZmVyZW5jZSAoUmVzaWR1YWxzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCiAgCiAgIyBTYW1lIGFzIGFib3ZlLCBidXQgbm93IHdpdGggcGVyY2VudGFnZS5NVCBhcyBncmFkaWVudAogIHAxLjggPC0gcWMubWV0cmljcyAlPiUKICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogIGdncGxvdChhZXMoeD1jb21wbGV4aXR5X2RpZmYsIHk9cGVyY2VudC5MYXJnZXN0LkdlbmUsIGNvbG91cj1wZXJjZW50Lm10KSkgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihjb2xvdXJzID0gYygnYmxhY2snLCAncmVkMycsICdyZWQyJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogNikgLyAxMDApIC8gMTApLCAxKSkgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFscyB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMgKyBNVCAlIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAgIAogIAogICMgVmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiAlTVQgdnMgbkdlbmVzIG5hZCBuVU1JcwogIHAyIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmosIGZlYXR1cmUxID0gIm5GZWF0dXJlX1JOQSIsIGZlYXR1cmUyID0gInBlcmNlbnQubXQiLCBjb2xzID0gImJsYWNrIikgKyAKICAgIGdndGl0bGUocGFzdGUoIlBlcmNlbnQtTVQgdnMgbkdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MSkgKyAKICAgIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIAogICAgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQogIHAzIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmosIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLCBmZWF0dXJlMiA9ICJwZXJjZW50Lm10IiwgY29scyA9ICJibGFjayIpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJQZXJjZW50LU1UIHZzIG5VTUlzIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxMCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInJlZCIsIHNpemU9MSkgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNy41LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xKSArIAogICAgeWxhYigiUGVyY2VudCBNdGlvY2hvbmRyaWFsIEdlbmVzICglKSIpICsgCiAgICB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCiAgCiAgIyBQcmludCBwbG90cwogIHByaW50KHAyICsgcDMpCiAgcHJpbnQocDEgKyBwMS4xKSAjIG9yIFNBVkUKICBwcmludChwMS4yKQogIHByaW50KHAxLjMgKyBwMS40ICsgcDEuNSkKICBwcmludChwMS42ICsgcDEuNyArIHAxLjgpCiAgcmV0dXJuKCkKfQojIEFwcGx5IGZ1bmN0aW9uIGdldF92aW9sX1FDCnZpb2wgPC0gc2FwcGx5KHNvYmpfbGlzdCwgZ2V0X3Zpb2xfUUMpCgojIEZpbmQgdGhlIHVwcGVyIHF1YW50aWxlIGFibGluZXMgZm9yIFVNSSBhbmQgbkZlYXR1cmVzIHRoYXQgd2Ugd2FudCB0byBwbG90IGxhdGVyIGluIHRoZSBmaW5hbCBncmFwaHMKIyBUaGVzZSBhcmUgdGhlIHF1YW50aWxlcyBvZiB0aGUgdW5maWx0ZXJlZCBkYXRhClVNSS5xdWFudGlsZS5hYmxpbmUgPC0gYygpCmZlYXR1cmUucXVhbnRpbGUuYWJsaW5lIDwtIGMoKQpVTUkucXVhbnRpbGUuYWJsaW5lLmxvdyA8LSBjKCkKZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93IDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBpZiAoVU1JLnF1YW50aWxlLmhpZ2ggPj0gMCAmIFVNSS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0UpIHsKICAgIFVNSS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkNvdW50X1JOQSwgcHJvYj1VTUkucXVhbnRpbGUuaGlnaCkKICB9IGVsc2UgeyAKICAgIFVNSS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkNvdW50X1JOQSwgcHJvYj0wLjk4KQogICAgfQogIGlmIChmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5oaWdoKSA9PSBGQUxTRSkgewogICAgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkZlYXR1cmVfUk5BLCBwcm9iPWZlYXR1cmUucXVhbnRpbGUuaGlnaCkKICB9IGVsc2UgeyAKICAgIGZlYXR1cmUucXVhbnRpbGUuYWJsaW5lW2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjk4KQogIH0KICBpZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0UpIHsKICAgIFVNSS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5Db3VudF9STkEsIHByb2I9VU1JLnF1YW50aWxlLmxvdykKICB9IGVsc2UgeyAKICAgIFVNSS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5Db3VudF9STkEsIHByb2I9MC4wMikKICB9CiAgaWYgKGZlYXR1cmUucXVhbnRpbGUubG93ID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5sb3cpID09IEZBTFNFKSB7CiAgICBmZWF0dXJlLnF1YW50aWxlLmFibGluZS5sb3dbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkZlYXR1cmVfUk5BLCBwcm9iPWZlYXR1cmUucXVhbnRpbGUubG93KQogIH0gZWxzZSB7IAogICAgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjAyKQogIH0KfQoKIyMjIyMjIyMjIyMjIFNFQ09ORCBXQVkgVE8gRE8gSVQsIEZPUiBTQVZJTkcgSU1BR0VTICMjIyMjIyMjIyMjIyMjCiNmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKIyAgdjEgPC0gVmxuUGxvdChzb2JqX2xpc3RbW2ldXSwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQojICBwcmludCh2MSkgIyBTQVZFIElUIEZPUiBQSVBFCiAgCiMgIHAxIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIiwgY29scyA9ICJibGFjayIsICkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArIGdndGl0bGUocGFzdGUoIm5VTUlzIHZzIG5HZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkKIyAgcDIgPC0gRmVhdHVyZVNjYXR0ZXIoc29ial9saXN0W1tpXV0sIGZlYXR1cmUxID0gIm5GZWF0dXJlX1JOQSIsIGZlYXR1cmUyID0gInBlcmNlbnQubXQiLCBjb2xzID0gImJsYWNrIikgKyBnZ3RpdGxlKHBhc3RlKCJQZXJjZW50LU1UIHZzIG5HZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeWxhYigiUGVyY2VudCBNdGlvY2hvbmRyaWFsIEdlbmVzICglKSIpICsgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpCiMgIHAzIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIGdndGl0bGUocGFzdGUoIlBlcmNlbnQtTVQgdnMgblVNSXMiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgTm9MZWdlbmQoKQojICBwcmludChwMSkgIyBvciBTQVZFCiMgIHByaW50KHAyKSAKIyAgcHJpbnQocDMpICAgCmBgYAoKCmBgYHtyIGNwbSBub3JtYWxpemF0aW9uLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayB0YWtlcyBDUE0oMTAuMDAwKSBub3JtYWxpemVzIHRoZSByYXcgY291bnQgbWF0cml4IGFuZCBhcHBlbmRzIGl0IGluIGEgbmV3IGRhdGEgc2xvdAojIC8vIFRoZSByYXcgY291bnQgbWF0cml4IHdpbGwgbm90IGJlIHRyYW5zZm9ybWVkIGFuZCBuYXRpdmUgdmVyc2lvbiB3aWxsIGJlIHN0b3JlZCBpbiBpdHMgcHJldmlvdXMgc2xvdAojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYXBwbGllcyBhIENQTS1sb2coMTAuMDAwKSBub3JtYWxpemF0aW9uIG9uIHRoZSBjb3VudCBtYXRyaXggZm9yIGVhY2ggb2JqZWN0CiMgLy8gSW5wdXQgZmlsZSBtdXN0IGJlIGEgdmVjdG9yIG9mIFNldXJhdCBvYmplY3RzCkNQTV9ub3JtIDwtIGZ1bmN0aW9uKHNvYmopIHsKICBzb2JqIDwtIE5vcm1hbGl6ZURhdGEoc29iaiwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCiAgcmV0dXJuKHNvYmopCn0KIyBFeGVjdXRlIENQTV9ub3JtIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBDUE1fbm9ybSkKYGBgCgojIyMjIFZpc3VhbGl6ZSB0aGUgaGlnaHkgdmFyaWFibGUgZ2VuZXM6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBXZSBmaXJzdCBlbXBsb3kgYSBsb2cgbm9ybWFsaXphdGlvbiBtZXRob2QgdGhhdCBub3JtYWxpemVzIHRoZSBnZW5lIGV4cHJlc3Npb24gY291bnRzIGZvciBlYWNoIGNlbGwgYnkgdGhlIHRvdGFsIGV4cHJlc3Npb24gYW5kIG11bHRpcGx5IHRoaXMgYnkgYSBzY2FsZSBmYWN0b3Igb2YgMTAsMDAwIGFuZCBsb2cgdHJhbnNmb3JtIGl0IHRvIHN0YWJpbGl6ZSB0aGUgdmFyaWFuY2Ugc28gdGhhdCBsYXJnZXIgdmFsdWVzIGRvIG5vdCBkb21pbmF0ZSBvdmVyIHNtYWxsZXIgb25lcy4KCiogVGhlbiB0aGUgdG9wIDIsNTAwIGdlbmVzICh1c2VyLWFkanVzdGFibGUpIHdpdGggbGFyZ2VzdCBzdGFuZGFyZGl6ZSB2YXJpYW5jZSB3aWxsIGJlIHNlbGVjdGVkIGF1dG9tYXRpY2FsbHkgYW5kIHVzZWQgZm9yIHRoZSBjbHVzdGVyaW5nLiBCeSBzZWxlY3RpbmcgaGlnaGx5IHZhcmlhYmxlIGdlbmVzLCB3ZSBlbnN1cmUgdGhhdCBob3VzZS1rZWVwaW5nIGdlbmVzIHdpdGggc2ltaWxhciBleHByZXNzaW9ucyBhY3Jvc3MgZGlmZmVyZW50IGNlbGxzIGRvIG5vdCBpbnRlcmZlcmUgd2l0aCB0aGUgdW5zdXBlcnZpc2VkIGNsdXN0ZXJpbmcuIAoKKiBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gZGVmaW5pdGl2ZSBhbnN3ZXIgb24gaG93IG1hbnkgZ2VuZXMgb25lIHNob3VsZCBpbmNsdWRlIGZvciBjbHVzdGVyaW5nLiBUaHVzIGl0IGlzIHJlY29tbWVuZGVkIHRvIGNhcmVmdWxseSBjb25zaWRlciB0aGUgcmlnaHQgbnVtYmVyIG9yIGJ5IHRyeWluZyBhIHJhbmdlIG9mIDIwMDAtNTAwMCB2YXJpYWJsZSBnZW5lcy4gR2VuZXJhbGx5LCBsb3ctY29tcGxleGl0eSBkYXRhIChpLmUuIGRhdGEgd2l0aCBzaW1pbGFyIGNlbGxzKSB3aWxsIGhhdmUgbG93ZXIgbnVtYmVyIG9mIHZhcmlhYmxlIGdlbmVzIHdoZW4gY29tcGFyZWQgdG8gY29tcGxleCB0aXNzdWUuIEJ5IGRlZmF1bHQsIHdlIHdpbGwgc2VsZWN0IDI1MDAgaGlnaGx5IHZhcmlhYmxlIGdlbmVzLiAKCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIE1vc3QgVmFyaWFibGUgR2VuZXM6CiAgLSBUaGUgcGxvdCBzaG91bGQgbm90IGxvb2tzIGxpa2UgYSBmbGF0IGxpbmUuIFRoZXJlIHNob3VsZCBiZSBhIGNsZWFyIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZ2VuZXMgd2l0aCB0aGUgbW9zdCBoaWdobHkgdmFyaWFibGUgb24gdGhlIHRvcC4gSWYgdGhlcmUgYXJlIG5vIGhpZ2hseSB2YXJpYWJsZSBnZW5lcyBpbiB5b3VyIGRhdGEsIHRoZW4geW91IGFyZSBsaWtlbHkgZGVhbGluZyB3aXRoIGNlbGxzIHRoYXQgaGF2ZSBzaW1pbGFyIGV4cHJlc3Npb24gbGV2ZWxzIG9mIHRoZSBzYW1lIGdlbmVzLiBUaGlzIGNhbiBkcmFzdGljYWxseSBpbXBhY3QgdGhlIGNsdXN0ZXJpbmcgYW5kIGFtYmllbnQgUk5BIGNvcnJlY3Rpb24gYXMgbW9zdCBkb3duc3RyZWFtIHN0ZXBzIGFyZSBjb21wdXRlZCBvbmx5IG9uIHRoZXNlIGdlbmVzLgpgYGB7ciBzaG93IG1vc3QgdmFyaWFibGUgZ2VuZXMsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHRha2VzIGFuZCB0aGUgY2FsY3VsYXRlZCB0aGUgdXNlciBzcGVjaWZpZWQgKG9yIGRlZmF1bHQgMjUwMCkgaGlnaGx5IHZhcmlhYmxlIGdlbmVzIHRvIGJlIHVzZWQgZm9yIGxhdGVyIGNsdXN0ZXJpbmcKIyAvLyBIaWdoIHZhcmlhYmlsaXR5IGlzIGZvdW5kIGJ5IGNhbGN1bGF0aW5nIHRoZSBzdGFuZGFyZGl6ZWQgdmFyaWFuY2UgYXMgZnVuY3Rpb24gb2YgbWVhbiBleHByZXNzaW9uCiMgLy8gT25seSB0aGVzZSBnZW5lcyB3aWxsIGJlIGNvbnNpZGVyZWQgZm9yIHVuc3VwZXJ2aXNlZCBjbHVzdGVyaW5nIG9mIHRoZSBjZWxscwojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMsIHBsb3RzIGFuZCByZXR1cm5zIHRoZSB0b3AgMjAwMCBtb3N0IHZhcmlhYmxlIGdlbmVzIGJhc2VkIG9uIHRoZSBzdGFuZGFyZGl6ZWQgdmFyaWFuY2UKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKbW9zdF92YXJfZ2VuZXMgPC0gZnVuY3Rpb24oc29iaikgewogIGlmIChuZmVhdHVyZXMgPj0gMCAmIG5mZWF0dXJlcyA8PSA1MDAwICYgbmZlYXR1cmVzID49IDIwMDAgJiBpcy5uYShuZmVhdHVyZXMpID09IEZBTFNFKXsKICAgIHNvYmogPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc29iaiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSBuZmVhdHVyZXMpICMjIyMgQU9UT01BVEUgVEhFIE5VTUJFUiBPRiBWQVJJQUJMRVMgKGJ1dCBiYXNlZCBvbiB3aGF0IGxvZ2ljPykKICB9IGVsc2UgewogICAgICBzb2JqIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNvYmosIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjUwMCkKICAgIH0KICAjIFNhdmUgdGhlIHRvcCAxMCBvZiB0aGUgMjAwMCBnZW5lcyAoZm9yIHZpc3VhbGl6YXRpb24pCiAgdG9wMTAuc29iaiA8LSBoZWFkKFZhcmlhYmxlRmVhdHVyZXMoc29iaiksIDEwKQogICMgUGxvdCB0aGUgbW9zdCB2YXJpYWJsZSBnZW5lcyBhbmQgdGhlIHRvcCAxMAogIHBsb3QxIDwtIFZhcmlhYmxlRmVhdHVyZVBsb3Qoc29iaikKICBwbG90MiA8LSBMYWJlbFBvaW50cyhwbG90ID0gcGxvdDEsIHBvaW50cyA9IHRvcDEwLnNvYmopCiAgcHJpbnQocGxvdDIgKyBnZ3RpdGxlKHBhc3RlKCJNb3N0IFZhcmlhYmxlIEdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSkKICAKICByZXR1cm4oc29iaikKfQojIEV4ZWN1dGUgbW9zdF92YXJfZ2VuZXMgZnVuY3Rpb24Kc29ial9saXN0IDwtIHNhcHBseShzb2JqX2xpc3QsIG1vc3RfdmFyX2dlbmVzKQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgVEVTVElORyBDT0RFIEZPUiBTSU5HTEVUUyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3NvYmogPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc29iaiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyNTAwKSAjIyMjIEFPVE9NQVRFIFRIRSBOVU1CRVIgT0YgVkFSSUFCTEVTCiMgU2F2ZSB0aGUgdG9wIDEwIG9mIHRoZSAyMDAwIGdlbmVzIChmb3IgdmlzdWFsaXphdGlvbikKI3RvcDEwLnNvYmogPC0gaGVhZChWYXJpYWJsZUZlYXR1cmVzKHNvYmopLCAxMCkKIyBQbG90IHRoZSBtb3N0IHZhcmlhYmxlIGdlbmVzIGFuZCB0aGUgdG9wIDEwCiNwbG90MSA8LSBWYXJpYWJsZUZlYXR1cmVQbG90KHNvYmopCiNwbG90MiA8LSBMYWJlbFBvaW50cyhwbG90ID0gcGxvdDEsIHBvaW50cyA9IHRvcDEwLnNvYmopCiNwbG90MiArIGdndGl0bGUoIk1vc3QgVmFyaWFibGUgR2VuZXMiKQpgYGAKCgpgYGB7ciBzY2FsaW5nIG9mIHRoZSBkYXRhLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9NywgcmVzdWx0cz0naGlkZScsIGVjaG89RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgdGFrZXMgdGhlIG5vcm1hbGl6ZWQgbWF0cml4IHNsb3QgYW5kIHNjYWxlcyB0aGUgZGF0YSBhbmQgYXBwZW5kcyBpdCBpbiBhIG5ldyBzY2FsZWQuZGF0YSBzbG90CiMgLy8gRWFjaCBmZWF0dXJlIHdpbGwgYmUgY2VudGVyZWQgdG8gaGF2ZSBhIG1lYW4gb2YgMCBhbmQgc2NhbGVkIGJ5IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgZWFjaCBmZWF0dXJlIAojIC8vIFRoaXMgc3RlcCBnaXZlcyBlcXVhbCB3ZWlnaHQgdG8gdGhlIGdlbmVzLCBzbyB0aGF0IGhpZ2hseS1leHByZXNzZWQgZ2VuZXMgZG8gbm90IGRvbWluYXRlIGZvciBkb3duc3RyZWFtIChlLmcuIFBDQSBhbmQgY2x1c3RlcmluZykKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBzaGlmdHMgdGhlIGV4cHJlc3Npb24gb2YgZWFjaCBnZW5lLCBzbyB0aGF0IHRoZSBtZWFuIGV4cHJlc3Npb24gYWNyb3NzIGNlbGxzIGlzIDAgCiMgLy8gVGhpcyBmdW5jdGlvbnMgc2NhbGVzIHRoZSBleHByZXNzaW9uIG9mIGVhY2ggZ2VuZSwgc28gdGhhdCB0aGUgdmFyaWFuY2UgYWNyb3NzIGNlbGxzIGlzIDEKIyAvLyBUaGUgZnVuY3Rpb24gcmV0dXJucyB0aGUgc2NhbGVkIHJlc3VsdHMgdG8gb2JqZWN0QHNjYWxlLmRhdGEgZm9yIGVhY2ggU2V1cmF0IG9iamVjdAojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwpzY2FsaW5nIDwtIGZ1bmN0aW9uKHNvYmopIHsKICBhbGwuZ2VuZXMuc29iaiA8LSByb3duYW1lcyhzb2JqKQogIHNvYmogPC0gU2NhbGVEYXRhKHNvYmosIGZlYXR1cmVzID0gYWxsLmdlbmVzLnNvYmopIAogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSBzY2FsaW5nIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBzY2FsaW5nKQoKCiMgRXZlbiB0aG91Z2ggd2UgZ290IHJpZCBvZiBjZWxscyB0aGF0IGhhZCBhIGxvdCBvZiBNVCBSTkEsIHRoZXJlIG1pZ2h0IHN0aWxsIGJlIHNvbWUgY2VsbHMgcmVtYWluIHRoYXQgaGF2ZSBoaWdobHkgdmFyaWFibGUgTVQgUk5BCiMgU28gd2Ugd2lsbCByZWdyZXNzIG91dCBhbGwgdGhlIE1UIHJ1YmJpc2gKIyBzY2FsZSB1c2luZyBhbGwgZ2VuZXMgYW5kIHJlZ3Jlc3Mgb3V0IHJlbWFpbmluZyBoaWdobHkgdmFyaWFibGUgTVQgZ2VuZXMgaXMgdGhlcmUgaXMgYW55IGxlZnQ6CiNzb2JqIDwtIFNjYWxlRGF0YShzb2JqLCBmZWF0dXJlcyA9IGFsbC5nZW5lcy5zb2JqLCB2YXJzLnRvLnJlZ3Jlc3MgPSAncGVyY2VudC5tdCcpIAoKI3NjYWxlLnRvcC5zb2JqIDwtIFNjYWxlRGF0YShzb2JqKSAjLCB2YXJzLnRvLnJlZ3Jlc3MgPSAncGVyY2VudC5tdCcpICMgaGVyZSB3ZSBvbmx5IHNjYWxlIHRoZSAyMDAwIHByZXZpb3VzIGhpZ2hseSB2YXJpYWJsZSBnZW5lcwpgYGAKCiMjIyMgVW5zdXBlcnZpc2VkIGNsdXN0ZXJpbmc6IFBDQSAjIyMjCgojIyMjIyBEZXNjcmlwdGlvbjogIyMjIyMKCiogSGVyZSwgd2UgY2Fycnkgb3V0IGEgbGluZWFyIGRpbWVuc2lvbmFsIHJlZHVjdGlvbiB1c2luZyBQQ0Egb24gdGhlIHNjYWxlZCBkYXRhIGNvbnRhaW5pbmcgdGhlIG1vc3QgdmFyaWFibGUgZ2VuZXMgKGFzIGNob3NlbiBiZWZvcmUpOgogIC0gQmVmb3JlIHB1dHRpbmcgdGhlIGhpZ2hseSB2YXJpYWJsZSBnZW5lcyBpbnRvIFBDQSwgd2Ugd2lsbCBzcGVjaWZpY2FsbHkgc2NhbGUgdGhvc2UgZ2VuZXMgc28gdGhhdCB0aGV5IGhhdmUgYSBtZWFuIG9mIDAgYW5kIGEgdmFyaWFuY2Ugb2YgMS4gTW9yZSBzcGVjaWZpY2FsbHksIEZvciBlYWNoIGhpZ2hseSB2YXJpYWJsZSBnZW5lLCBhIHJlZ3Jlc3Npb24gbW9kZWwgaXMgYnVpbGQgdXNpbmcgdGhhdCBnZW5lJ3MgZXhwcmVzc2lvbiBsZXZlbCBhY3Jvc3MgYWxsIGNlbGxzLCBhbmQgdGhlbiBzaGlmdCB0aGUgcmVzaWR1YWwgdG8gemVybyBhbmQgZGl2aWRlZCBpdCBieSBzdGFuZGFyZCBkZXZpYXRpb24uCiAgLSBXZSBhcmUgZXNzZW50aWFsbHkgc2NhbGluZyBhbmQgY2VudGVyaW5nIHRoZXNlIGdlbmVzIGluIHRoZSBkYXRhc2V0LCB3aGljaCBzdGFuZGFyZGl6ZXMgdGhlIHJhbmdlIG9mIGV4cHJlc3Npb24gdmFsdWVzLiBUaGlzIHdpbGwgcmVncmVzc2VzIG91dCB1bndhbnRlZCBzb3VyY2VzIG9mIHZhcmlhdGlvbiBzdWNoIGFzIHRlY2huaWNhbCBub2lzZSBhbmQgZWFjaCBnZW5lIHdpbGwgY29udHJpYnV0ZXMgc2ltaWxhcmx5IHRvIHRoZSBkb3duc3RyZWFtIHN0ZXBzLiBBcyBhIHJlc3VsdCwgdGhlIFBDQSBhbmQgY2x1c3RlcmluZyB3aWxsIG5vdCBiZSBkb21pbmF0ZWQgYnkgdGhlIHNpZ25hbCBvZiBhIGZldyBoaWdobHktZXhwcmVzc2VkIGdlbmVzLgogIAoqIFRoZSByZWFzb24gdGhhdCB3ZSBkbyBhIFBDQSBpcyBiZWNhdXNlIHdlIHNpbXBseSBjYW5ub3Qgd29yayB3aXRoIHRoaXMgdWx0cmEgaGlnaCBkaW1lbnNpb25hbCBkYXRhIGZvciB0aGUgZG93bnN0cmVhbSBhbmFseXNpcy4gSW5zdGVhZCB3ZSBjYW4gbG9vayBhdCB3aGljaCBvZiB0aGUgbW9zdCB2YXJpYWJsZSBnZW5lcyBleHBsYWlucyBtb3N0IG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGF0YS4KICAKKiBOb3RlIHRoZSBQQ0EgaXMgYSBzdWl0YWJsZSBtZXRob2QsIGJ1dCBoYXMgc29tZSBkaXNhZHZhbnRhZ2VzOgogIC0gKEkgc3RpbGwgYmVsaWV2ZSB0aGF0IE1MIHdvdWxkIGJlIGEgYmV0dGVyIG9wdGlvbiBoZXJlLCBidXQgaXQgaXMgbm90IGJlbmNobWFya2VkIGluIHNpbmdsZS1jZWxsIGRhdGEgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gUENBKS4KICAtIFBDQSBpcyB2ZXJ5IHBvcHVsYXIsIGJ1dCBmYWlscyB0byBjYXB0dXJlIGFsbCBzaWduYWxzIGNvbnNpZGVyaW5nIHRoYXQgMkQgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIGNhbm5vdCBjYXB0dXJlIGZhaW50IHNpZ25hbC4KCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIFBDQSBlbGJvdyBwbG90OiAgIFdlIHdpbGwgZmluZCB0aGUgb3B0aW1hbCBudW1iZXIgb2YgZGltZW5zaW9ucyBmb3IgZG93bnN0cmVhbSBhbmFseXNpcywgYmFzZWQgb246CiAgLSBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDElLgogIC0gT3IsIFBDcyByZXByZXNlbnRpbmcgY3VtdWxhdGl2ZSBwZXJjZW50ID45MCUgYW5kIGxlc3MgdGhhbiA1JSBhc3NvY2lhdGVkIHdpdGggdGhlIHNpbmdsZSBQQy4KICAtIFdpdGggZWFjaCBQQyByZXByZXNlbnRpbmcgY29tYmluZWQgaW5mb3JtYXRpb24gb2YgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGNvcnJlbGF0ZWQgZ2VuZSBzZXRzLCB0aGUgdG9wIFBDcyByZXByZXNlbnQgc3Ryb25nIGNvbXByZXNzaW9uIG9mIHRoZSB0b3RhbCBkYXRhc2V0IHRoYXQgY2FuIGJlIHVzZWQgZm9yIGZ1cnRoZXIgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIGFuZCBjbHVzdGVyaW5nLiBJZiB5b3UgZmluZCBsZXNzIHRoYW4gMTAgUENzIGluIHRoZSBlbGJvdyBwbG90LCB5b3VyIGRhdGEgbGlrZWx5IGNvbnRhaW5zIHRvbyBmZXcgcmVsZXZhbnQgZ2VuZXMgZm9yIHN1Y2Nlc3NmdWwgY2x1c3RlcmluZy4gQWZ0ZXIgYWxsLCB3ZSBhcmUgbG9va2luZyBmb3IgZ2VuZXMgdGhhdCBjYW4gZXhwbGFpbiB0aGUgdmFyaWFuY2UgaW4geW91ciBjZWxscywgYW5kIGlmIG5vIHN1Y2ggZ2VuZXMgY2FuIGJlIGZvdW5kIChvciB0b28gZmV3IG9mIHRoZW0pIHRoZW4gdGhlIGRvd25zdHJlYW0gc3RlcHMgd2lsbCBoYXZlIGRpZmZpY3VsdGllcyB0byBmaW5kIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHlvdXIgY2VsbHMuIEhvd2V2ZXIsIGlmIHlvdSBhcmUgd29ya2luZyB3aXRoIGxvdy1jb21wbGV4aXR5IGRhdGEgKGUuZy4gc2ltaWxhciBjZWxsIHR5cGVzIGluIGRpZmZlcmVudCBiaW9sb2dpY2FsIHN0YXRlcykgdGhlbiB5b3Ugc2hvdWxkIHRvIGZpbmQgZmV3ZXIgbnVtYmVyIG9mIFBDcy4KICAtIFRoZSBkYXNoZWQgcmVkIGxpbmUgaW4gdGhlIHBsb3Qgc2hvd3MgdGhlIG9wdGltYWwgbnVtYmVyIFBDIGRpbWVuc2lvbnMuCmBgYHtyIHNjYWxpbmcgYW5kIFBDQSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgdGFrZXMgdGhlIHNjYWxlZCBub3JtYWxpemVkIG1hdHJpeCBhbmQgcGVyZm9ybXMgUENBIG9uIG4gdXNlciBkZWZpbmVkIGhpZ2hseSB2YXJpYWJsZSBmZWF0dXJlcwojIC8vIFRoZSBzdG9yZWQgUENBIGluZm9ybWF0aW9uIHdpbGwgbGV2ZXJhZ2VkIGJ5IGEgc2Vjb25kIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgb3B0aW1hbCBQQ3MgZm9yIGNsdXN0ZXJpbmcKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBydW5zIGEgUENBIG9uIHRoZSBuIHVzZXIgZGVmaW5lZCAob3IgZGVmYXVsdCkgbW9zdCB2YXJpYWJsZSBlYWNoIG9iamVjdCAKIyAvLyBCeSBkZWZhdWx0IHVwIHRvIDEwMCBQQ3MgYXJlIGNhbGN1bGF0ZWQKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKcnVuX1BDQSA8LSBmdW5jdGlvbihzb2JqKSB7CiAgc29iaiA8LSBSdW5QQ0Eoc29iaiwgZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IHNvYmopKQogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSBydW5fUENBIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBydW5fUENBKQoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyByZXR1cm5zIHRoZSBvcHRpbWFsIG51bWJlciBvZiBQQ3MgZm9yIGNsdXN0ZXJpbmcuCiMgLy8gTWV0aG9kMTogbGFzdCBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDAuNSUKIyAvLyBNZXRob2QyOiBQQ3MgcmVwcmVzZW50aW5nIGN1bXVsYXRpdmUgcGVyY2VudCA+OTAlIGFuZCBsZXNzIHRoYW4gNSUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzaW5nbGUgUEMKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKb3B0aW1hbF9QQ3MgPC0gZnVuY3Rpb24oc29iaikgewogIHBjLnN0ZGV2LnBlcmNlbnRhZ2UgPC0gc29ialtbInBjYSJdXUBzdGRldiAvIHN1bShzb2JqW1sicGNhIl1dQHN0ZGV2KSAqIDEwMCAjIGZpbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciBlYWNoIFBDCiAgY3VtdS5wZXJjZW50YWdlIDwtIGN1bXN1bShwYy5zdGRldi5wZXJjZW50YWdlKSAjIGZpbmQgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyBmb3IgUENzCiAgY28xIDwtIHdoaWNoKGN1bXUucGVyY2VudGFnZSA+IDkwICYgcGMuc3RkZXYucGVyY2VudGFnZSA8IDUpWzFdICMgZmluZCBQQ3MgcmVwcmVzZW50aW5nIGN1bXVsYXRpdmUgcGVyY2VudCA+OTAlIGFuZCBsZXNzIHRoYW4gNSUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzaW5nbGUgUEMKICBjbzEgIyBsaXN0IFBDCiAgY28yIDwtIHNvcnQod2hpY2goKHBjLnN0ZGV2LnBlcmNlbnRhZ2VbMTpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSkgLSAxXSAtIHBjLnN0ZGV2LnBlcmNlbnRhZ2VbMjpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSldKSA+IDAuMDEpLCAKICAgICAgICAgICAgICBkZWNyZWFzaW5nID0gVClbMV0gIysgMSAjIGZpbmQgbGFzdCBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDElIGFuZCBhZGQgYW5kIGV4dHJhIFBDIHRvIGl0CiAgY28yICMgbGlzdCBQQwogIHBjcyA8LSBtaW4oY28xLCBjbzIpICMgZmluZCB0aGUgbWluaW11bSBQQyBmcm9tIHRoZSAyIG1ldGhvZHMgdXNlZCBhYm92ZQogIHBjcyA8IG1heChwY3MpICMgbGlzdCBQCiAgcGMuZGltcyA8LSAxOnBjcyAjIHdlIHdpbGwgdXNlIHRoZXNlIGRpbWVuc2lvbiBsYXRlciBvbgogIAogIHBsb3RfZGYgPC0gZGF0YS5mcmFtZShwYy5zdGRldi5wZXJjZW50YWdlID0gcGMuc3RkZXYucGVyY2VudGFnZSwgIyBwdXQgUEMgdmFsdWVzIGludG8gZGF0YWZyYW1lIGZvciBwbG90dGluZwogICAgICAgICAgICAgICAgICAgICAgY3VtdSA9IGN1bXUucGVyY2VudGFnZSwgCiAgICAgICAgICAgICAgICAgICAgICByYW5rID0gMTpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSkpCiAgCiAgb3B0X1BDX3Bsb3QgPC0gZ2dwbG90KHBsb3RfZGYsIGFlcyhjdW11LnBlcmNlbnRhZ2UsIHBjLnN0ZGV2LnBlcmNlbnRhZ2UsIGxhYmVsID0gcmFuaywgY29sb3IgPSByYW5rID4gcGNzKSkgKyAKICAgIGdlb21fdGV4dCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gOTAsIGNvbG9yID0gImdyZXkiKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbWluKHBjLnN0ZGV2LnBlcmNlbnRhZ2VbcGMuc3RkZXYucGVyY2VudGFnZSA+IDVdKSwgY29sb3IgPSAiZ3JleSIpICsgdGhlbWVfYncoKSAjIHZpc3VhbGl6ZSBQQ3MgdG8gdXNlIGluIGVsYm93IHBsb3QKICBwcmludChvcHRfUENfcGxvdCkKICAKICByZXR1cm4obGlzdChwYy5kaW1zKSkKfQojIEV4ZWN1dGUgb3B0aW1hbF9QQyBmdW5jdGlvbgpwYy5kaW1zIDwtIHNhcHBseShzb2JqX2xpc3QsIG9wdGltYWxfUENzKQoKCiNwcmludChpbGV1bS5vcmcuaW5jbC5pbnRyLnNldVtbJ3BjYSddXSwgZGltcyA9IDE6NSwgbmZlYXR1cmVzID0gNSkKI1ZpekRpbUxvYWRpbmdzKGlsZXVtLm9yZy5pbmNsLmludHIuc2V1LCBkaW1zID0gMToyLCByZWR1Y3Rpb24gPSAncGNhJykKIyBEaW1QbG90KGlsZXVtLm9yZy5pbmNsLmludHIuc2V1LCByZWR1Y3Rpb24gPSAncGNhJykKYGBgCgpgYGB7ciBQQ0EgZWxib3cgcGxvdCB0byBmaW5zIG1vc3Qgc2lnbmlmaWNhbnQgUENzLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD02LCBlY2hvPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHRha2VzIHBsb3RzIGFuIEVsYm93IHdpdGggb3B0aW1hbCBQQ3MgYmVpbmcgZGlzcGxheWVkCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBQbG90IGFuZCBFbGJvdyB0byB2aXN1YWxpemUgdGhlIG9wdGltYWwgUEMgYmFzZWQKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBwYy5kaW1zKSkgewogIGUxIDwtIEVsYm93UGxvdChzb2JqX2xpc3RbW2ldXSwgbmRpbXMgPSA0MCkgKyAKICAgIGdndGl0bGUocGFzdGUoIlNpZ25pZmljYW50IFBDcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBtYXgodW5saXN0KHBjLmRpbXNbW2ldXSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArIAogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQogIHByaW50KGUxKSAjIyMjIyMjIFNBVkUgRk9SIFBJUEVMSU5FCn0KYGBgCgpgYGB7ciBQQ0Egc2VsZWN0aW9uLCBmaWcuaGVpZ2h0PTE3LCBmaWcud2lkdGg9OSwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMgLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGhlYXRtYXBzIG9mIHRoZSB0b3AgMzAgUENzIG1ldGEgZ2VuZXMgb2YgNTAwIGNlbGxzIHBlciBQQwojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwpydW5fUENBX2hlYXRtYW4gPC0gZnVuY3Rpb24oc29iaikgewogIFBDQV9oZWF0bWFwIDwtIERpbUhlYXRtYXAoc29iaiwgZGltcyA9IDE6MzAsIGNlbGxzID0gNTAwLCBiYWxhbmNlZCA9IFRSVUUpICMgZmFzdCA9IEZBTFNFIHVzZXMgZ2dwbG90IAogIHByaW50KFBDQV9oZWF0bWFwKQogIHJldHVybigpCn0KCiMgRXhlY3V0ZSBydW5fUENBX2hlYXRtYW4gZnVuY3Rpb24KUENBX2hlYXRtYXBzIDwtIHNhcHBseShzb2JqX2xpc3QsIHJ1bl9QQ0FfaGVhdG1hbikKYGBgCgojIyMjIEZpbmFsIGNsdXN0ZXJpbmcgKEtOTiAoU05OKSkgdXNpbmcgdGhlIG1vc3QgZXhwbGFpbmVkIFBDcyBhbmQgcHJvamVjdGlvbiBvbnRvIFVNQVA6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBPcmlnaW5hbCBMb3V2YWluIGFsZ29yaXRobToKICAtIEJhc2VkIG9uIHRoZSBFdWNsaWRlYW4gZGlzdGFuY2UgaW4gdGhlIFBDQSBzcGFjZSwgdGhlIHBpcGVsaW5lIGNhcnJpZXMgb3V0IGEgSy1uZWFyZXN0IG5laWdoYm9yIGdyYXBoIChrPTIwIGJ5IGRlZmF1bHQpIGFuZCByZWZpbmVzIHRoZSBlZGdlIGJldHdlZW4gYW55IHR3byBjZWxscyBiYXNlZCBvbiBzaGFyZWQgb3ZlcmxhcCBiZXR3ZWVuIHRoZWlyIGV4cHJlc3Npb24gcGF0dGVybnMgdXNpbmcgdGhlIHRyYWRpdGlvbmFsIEphY2NhcmQgc2ltaWxhcml0eSB0ZWNobmlxdWUuIAogIC0gVGhlIGNsdXN0ZXJzIGFyZSB0aGVuIGNvbnN0cnVjdGVkIGJ5IGpvaW5pbmcgdGhlIGdyb3VwcyBpbnRlcmFjdGl2ZWx5IHVudGlsIGl0IGZ1bGx5IGNvbnZlcmdlcyB1c2luZyB0aGUgTG91dmFpbiBhbGdvcml0aG0uIENlbGxzIGFyZSB0aGVuIG1vdmVkIHRvIGEgbm9uLWxpbmVhciBVTUFQIHNwYWNlIGZvciB2aXN1YWxpemF0aW9uLiBIZXJlLCB3ZSBmaW5kIHRoYXQgYnkgdXNpbmcgYSByZXNvbHV0aW9uIG9mIDAuOCwgTG91dmFpbiBkb2VzIGEgZGVjZW50IGpvYiBpbiBpZGVudGlmeWluZyBzdWZmaWNpZW50IG51bWJlciBvZiBjb21tdW5pdGllcyBmb3IgYm90aCBoaWdoIGNvbXBsZXhpdHkgKHBvcmNpbmUgaWxldW0sIHdpdGggaW1tdW5lKSBhbmQgbG93LWNvbXBsZXhpdHkgZGF0YSAocG9yY2luZSBpbGV1bSBvcmdhbm9pZCBvciB0aXNzdWUsIG5vIGltbXVuZSkuCiAgLSBUbyByZXNvbHV0aW9uIG9mIDAuOCBpcyBzZXQgYXMgZGVmYXVsdCwgYnV0IG1vcmUgcmVzZWFyY2ggaXMgcmVxdWlyZWQgdG8gdXNlIGFuIGFkYXB0aXZlIHJlc29sdXRpb24gZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIGRhdGEgYXMgdGhpcyBwYXJhbWV0ZXIgY291bGQgZ3JlYXRseSBpbXBhY3QgdGhlIG51bWJlciBwcmVsaW1pbmFyeSBjbHVzdGVycyB0aGF0IHdpbGwgYmUgdXNlZCBieSB0aGUgYW1iaWVudCBSTkEgY29ycmVjdGluZyBhbGdvcml0aG0uIEFzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlLCB5b3UgYXJlIGFsbG93ZWQgdG8gY2hhbmdlIHRoZSByZXNvbHV0aW9uLCB3aGljaCB3aWxsIGltcGFjdCB0aGUgZmluYWwgbnVtYmVyIG9mIGNlbGwgY2x1c3RlcnMgKG5vdCByZWNvbW1lbmRlZCkuCiAgLSBJbiBjYXNlIHlvdSBlbmQgdXAgd2l0aCB0b28gZmV3IGNsdXN0ZXIgYnkgdGhlIGRlZmF1bHQgc2V0dGluZ3MsIHRoZW4gaXQgd29ydGggdG8gdHJ5IGEgcmVzb2x1dGlvbiA+MC44LiBJZiB5b3UgaGF2ZSB0b28gZmV3IGNsdXN0ZXJzLCB0aGUgYW1iaWVudCBSTkEgY29ycmVjdGlvbiBtaWdodCBiZWNvbWUgYmlhc2VkIChtb3JlIG9uIHRoaXMgbGF0ZXIuLi4pLgoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogVU1BUCBwbG90czogICBOdW1iZXIgb2YgZ2VuZXMvVU1Jcy9NVHMgYXJlIHNob3duIHBlciBjZWxsIHdpdGhpbiBlYWNoIGNsdXN0ZXI6CiAgLSBUaGVzZSBwbG90cyBjYW4gZ2l2ZSB1cyBhbiBpZGVhIHdoaWNoIGNlbGxzICh3aXRoaW4gY2x1c3RlcnMpIGNvbnRhaW4gbG93LCBtZWRpdW0gb3IgaGlnaCBudW1iZXIgb2YgZ2VuZXMgYW5kIHRvdGFsIFVNSXMuIAogIC0gTm90ZSB0aGF0IGhpZ2ggbnVtYmVyIG9mIGdlbmVzIG9yIFVNSXMgaXMgbm90IG5lY2Vzc2FyaWx5IGEgYmFkIHRoaW5nLCBidXQgaXMgc3RpbGwgaGlnaGxpZ2h0ZWQgd2l0aCAicHVycGxlIgogIC0gSW4gY2FzZSBvZiBhIGZhaWxlZCBleHBlcmltZW50IChsb3cgbnVtYmVyIG9mIGdlbmVzKSBkdWUgdG8gc2lnbmlmaWNhbnQgcG9wdWxhdGlvbiBvZiBjZWxscyB3aXRoIGEgbG93IFJOQSBjb250ZW50LCB0aGVzZSBwbG90cyBjYW4gc2hvdyB3aGljaCBncm91cHMgb2YgY2VsbHMgYXJlIGFmZmVjdGVkLiBBbmQgaWYgdGhlIHNhbWUgY2x1c3RlcnMgY29udGFpbiBoaWdoIHBlcmNlbnRhZ2UgTVQgZ2VuZXMsIHRoZW4gaXQgaXMgbGlrZWx5IHRoYXQgdGhvc2UgY2VsbHMgYXJlIGxvdy1xdWFsaXR5IG9yIGRlYWQuCiAgLSBIb3cgbWFueSBjbHVzdGVyIGRvIHlvdSBvYnNlcnZlIGluIHRvdGFsPyBEbyB5b3UgZXhwZWN0IHRvIHNlZSBtb3JlIChvciBsZXNzKSBiYXNlZCBvbiB3aGF0IHlvdSBhbHJlYWR5IGtub3cgYWJvdXQgeW91ciBzYW1wbGVzPwpgYGB7ciBtYWtlIHVtYXAsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHBlcmZvcm1zIHRoZSB1bnN1cGVydmlzZWQgTG91dmFpbiBncmFwaCBiYXNlZCBjbHVzdGVyaW5nIHVzaW5nIHRoZSBvcHRpbWFsIFBDQSBtZXRhZmVhdHVyZXMgZnJvbSB0aGUgbiB1c2VyIGRlZmluZWQgaGlnaGx5IHZhcmlhYmxlIGdlbmVzCiMgLy8gVXNpbmcgdGhlIHZhbHVlcyBvZiB0aGUgbW9zdCByZWxldmFudCBQQ3MgdGhlIGNlbGxzIGFyZSBmb3J3YXJkZWQgaW50byBhIFVNQVAgcHJvamVjdGlvbgojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgY2x1c3RlcmluZyBieSBjYWxjdWxhdGluZyBrLW5lYXJlc3QgbmVpZ2hib3JzIGFuZCBjb25zdHJ1Y3QgdGhlIFNOTiBncmFwaCBieSB0aGUgb3JpZ2luYWwgTG91dmFpbiBhbGdvcml0aG0gdXNpbmcgdGhlIG9wdGltYWwgUENBIGRpbWVuc2lvbnMKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBzYW1wbGVfbmFtZXMpKSB7CiAgc29ial9saXN0W1tpXV0gPC0gRmluZE5laWdoYm9ycyhzb2JqX2xpc3RbW2ldXSwgay5wYXJhbSA9IDIwLCBkaW1zID0gdW5saXN0KHBjLmRpbXNbW2ldXSkpICMgRmluZCBuZWlnaGJvcnMgb24gYnkgdXNpbmcgS05OIChrPTIwKSBhbmQgU05OIG5laWdoYm9yaG9vZCBvdmVybGFwIHVzaW5nIGphY2NhcmQgaW5kZXguCiAgc29ial9saXN0W1tpXV0gPC0gRmluZENsdXN0ZXJzKHNvYmpfbGlzdFtbaV1dLCByZXNvbHV0aW9uID0gdW1hcC5yZXNvbHV0aW9uKSAjIFdlIGRvIG5ldCB5ZXQgc2VsZWN0IGRpZmZlcmVudCByZXNvbHV0aW9ucyBhcyB0aGlzIGlzIHVubmVjZXNzYXJ5IGZvciBub3cuLi4gCiAgIyBMb29rIGF0IGNsdXN0ZXIgSURzIG9mIHRoZSBmaXJzdCA1IGNlbGxzCiAgIyBoZWFkKElkZW50cyhpbGV1bS5vcmcuaW5jbC5pbnRyLnNldSksIDUpLiAjIHRlc3QgY29kZQogICMgQ2FsY3VsYXRlIGFuZCBtYWtlIHRoZSBVTUFOIGFuZCBULVNORSBjbHVzdGVycwogIHNvYmpfbGlzdFtbaV1dIDwtIFJ1blVNQVAoc29ial9saXN0W1tpXV0sIGRpbXMgPSB1bmxpc3QocGMuZGltc1tbaV1dKSkKIyAgc29ial9saXN0W1tpXV0gPC0gUnVuVFNORShzb2JqX2xpc3RbW2ldXSwgZGltcyA9IHVubGlzdChwYy5kaW1zW1sxXV0pKQogIGQxIDwtIERpbVBsb3Qoc29ial9saXN0W1tpXV0sIHJlZHVjdGlvbiA9ICd1bWFwJywgbGFiZWwgPSBGQUxTRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJTTk46IFVNQVAiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCBzdWJ0aXRsZSA9IHBhc3RlKCJOdW1iZXIgb2YgQ2VsbHMgKG4gPSAiLCBwYXN0ZShkaW0oc29ial9saXN0W1tpXV0pWzJdLCAiKSIsIHNlcCA9ICIiKSkpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQogIGQyIDwtIEZlYXR1cmVQbG90KHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlcz0ibkZlYXR1cmVfUk5BIiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIkdlbmUgQ291bnQgcGVyIENsdXN0ZXIvQ2VsbCIpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgbGFicyhmaWxsID0gIm5HZW5lcyIsIGNvbG91ciA9ICJuR2VuZXMiLCBsYWJlbHMgPSAibkdlbmVzIiApICsgc2NhbGVfY29sb3VyX2dyYWRpZW50bihjb2xvdXJzID0gYygncmVkJywgImdyZWVuIiwgJ3B1cnBsZScpLCB2YWx1ZXMgPSBjKDAsICgyMDAgLyBtYXgoc29ial9saXN0W1sxXV1bWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BKSksIDEpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKIyAgZDIgPC0gRGltUGxvdChzb2JqX2xpc3RbW2ldXSwgcmVkdWN0aW9uID0gJ3RzbmUnLCBsYWJlbCA9IFRSVUUpICsgZ2d0aXRsZShwYXN0ZSgiU05OOiB0LVNORSIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeGxhYigidC1TTkUgMiIpCiAgZDMgPC0gRmVhdHVyZVBsb3Qoc29ial9saXN0W1tpXV0sIGZlYXR1cmVzPSJuQ291bnRfUk5BIiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIlVNSSBDb3VudCBwZXIgQ2x1c3Rlci9DZWxsIikgKyAKICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikgKyBsYWJzKGZpbGwgPSAiblVNSXMiLCBjb2xvdXIgPSAiblVNSXMiLCBsYWJlbHMgPSAiblVNSXMiICkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdyZWQnLCAiZ3JlZW4iLCAncHVycGxlJyksIHZhbHVlcyA9IGMoMCwgKDUwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSkpLCAxKSkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCiAgZDQgPC0gRmVhdHVyZVBsb3Qoc29ial9saXN0W1tpXV0sIGZlYXR1cmVzPSJwZXJjZW50Lm10IiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIk1UIFBlcmNlbnRhZ2UgcGVyIENsdXN0ZXIvQ2VsbCIpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgbGFicyhmaWxsID0gIk1UICUiLCBjb2xvdXIgPSAiTVQgJSIsIGxhYmVscyA9ICJNVCAlIiApICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdncmVlbicsICdyZWQnLCAncmVkNCcpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqX2xpc3RbW2ldXVtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgKiA0KSAvIDEwMCkgLyAxMCksIDEpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKICAjIFByaW50IHRoZSBwbG90cwogIHByaW50KGQxKQogIHByaW50KGQyKQogIHByaW50KGQzKQogIHByaW50KGQ0KQp9CgoKIyBTY2FsZWQgY29sb3IgZ3JhZGllbnQgdmFsdWVzIGZvciAic2NhbGVfY29sb3VyX2dyYWRpZW50biIgbWlkIHZhbHVlcwojKCgobWF4KHNvYmpfbGlzdFtbMV1dW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDEwMCkgLyAxMDApIC8gMTApICMgcGVyY2VudC5tdAojKDIwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEpKSAjIG5GZWF0dXJlX1JOQQojKDUwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSkpICMgbkNvdW50X1JOQQoKIyJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IgpgYGAKCiMjIyMgU291cFggQW1iaWVudCBSTkEgUmVtb3ZhbDogIyMjIwoKIyMjIyMgRGVzY3JpcHRpb246ICMjIyMjCgoqIFRlcm1pbm9sb2d5OgogIC0gVG90YWwgY29udGFtaW5hdGlvbiBpcyB0aGUgZnJhY3Rpb24gb2YgYW1iaWVudCBSTkEgKGZvciBlYWNoIGdlbmUpIGVzdGltYXRlZCBmcm9tIChzZW1pKS1lbXB0eSBkcm9wbGV0cyBmcm9tIHRoZSByYXcgY291bnRzIG1hdHJpeC4KICAtIENvbnRhbWluYXRpb24gZnJhY3Rpb25zIGlzIHRoZSB0aGUgZXN0aW1hdGVkIHRoZSBudW1iZXIgdHJhbnNjcmlwdHMgdGhhdCBhcmUgY29udHJpYnV0aW5nIHRvIHRoZSBwcmV2aW91c2x5IGNhbGN1bGF0ZWQgYmFja2dyb3VuZCBjb250YW1pbmF0aW9uIChmcm9tIGVtcHR5IGRyb3BsZXRzKSB1c2luZyB0aGUgZXhwcmVzc2lvbiBvZiBzZXZlcmFsIG1hcmtlciBnZW5lcyBiZXR3ZWVuIGNlbGwtY2x1c3RlcnMgd2hlcmUgaXQgZG9lcyBub3QgYmVsb25nLiBIZXJlIGl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgYWJ1bmRhbmNlIG9mIGdlbmVzIHRoYXQgbWFrZSB1cCB0aGUgYmFja2dyb3VuZCBhcmUgbm90IGRpZmZlcmVudCBiZXR3ZWVuIHRoZSBjZWxscy4gCgoqIFRoZSBhaW0gb2YgU291cFggaXMgdG8gZXN0aW1hdGUgd2hhdCBmcmFjdGlvbiBvZiB0aGUgdHJhbnNjcmlwdHMgYXJlIGRlcml2ZWQgYXMgYW1iaWVudCBpbiBlYWNoIGRyb3BsZXQgYW5kIHRvIGdlbmVyYXRlIGEgY29ycmVjdGVkIGdlbmUgY291bnRzIG1hdHJpeCB3aXRoIHRoZSBjb250YW1pbmF0ZWQgY291bnRzIHJlbW92ZWQuIFRoZSBhbGdvcnRobSB0YWtlIHRoZSBmb2xsb3dpbmcgc3RlcHM6CiAgLSBJdCBmaXJzdCBjYWxjdWxhdGVzIHRoZSBleHByZXNzaW9uIHByb2ZpbGUgb2YgdGhlIHRvdGFsIGNvbnRhbWluYXRpb24gYnkgZXN0aW1hdGluZyB0aGUgYW1iaWVudCBSTkEgZXhwcmVzc2lvbiBmcm9tIHRoZSByYXcgY291bnRzLW1hdHJpeCBvYnRhaW5lZCBmcm9tIHRoZSBDZWxsUmFuZ2VyIG91dHB1dC4gUmVnYXJkbGVzcyBvZiB0aGUgdXNlciBjaG9pY2UsIGluIHRoaXMgc3RlcCB3ZSBhbHdheXMgdXRpbGl6ZSB0aGUgcmF3IGNvdW50cyBhcyB0aGlzIGRhdGEgY29udGFpbnMgaW5mb3JtYXRpb24gb2YgZW1wdHkgZHJvcGxldHMsIHdoaWNoIGlzIGFuIGV4Y2VsbGVudCBjYW5kaWRhdGUgdG8gYW5hbHl6ZSBjZWxsLWZyZWUgZHJvcGxldHMgdGhhdCBtYXkgY29udGFpbiBhbWJpZW50IFJOQSBmb3IgZWFjaCBnZW5lLiAoSWYgZm9yIHNvbWUgcmVhc29uIHRoZSByYXcgY291bnRzIGFyZSBub3QgYXZhaWxhYmxlLCBTb3VwWCB3aWxsIG5vdCBydW4sIGFuZCB0aGUgcGlwZWxpbmUgd2lsbCBjb250aW51ZSB3aXRob3V0IHRoZSBjb3JyZWN0aW9uIG9mIGFtYmllbnQgUk5BKS4KICAtIE9uY2UgdGhlIHRvdGFsIGNvbnRhbWluYXRpb24gaGFzIGJlZW4gZXN0aW1hdGVkLCBTb3VwWCBjYWxjdWxhdGVzIHRoZSBjZWxsIHNwZWNpZmljIGNvbnRhbWluYXRpb24gbGV2ZWwgYnkgdXNpbmcgdGhlIHByZXZpb3VzbHkgZm91bmQgY2VsbCBjbHVzdGVycy4gVGhlIHBvaW50IGhlcmUgaXMgdG8gZmluZCBhIHNldCBvZiBnZW5lcyBpbiBlYWNoIGNlbGwgdGhhdCBpcyBrbm93biBub3QgYmUgZXhwcmVzc2VkIGluIG90aGVycywgYW5kIHRoZW4gZXN0aW1hdGUgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gdXNpbmcgdGhlIGV4cHJlc3Npb24gb2YgdGhhdCBnaXZlbiBnZW5lIGluIGNlbGxzIGl0IGRvZXMgbm90IGJlbG9uZy4gSWYgeW91IGhhdmUgdG9vIGZldyBjbHVzdGVyIChkdWUgdG8gbGFjayBoaWdobHkgdmFyaWFibGUgZ2VuZXMgYW5kIGluc3VmZmljaWVudCBudW1iZXIgUEMgZGltZW5zaW9ucyksIHRoZW4gaXQgaXMgYWR2aXNlZCB0byBjaGFuZ2UgbnVtYmVyIG9mIFVNQVAgZGltZW5zaW9ucyA+MC44LiBUcnkgaXQgb3V0IGFuZCBzZWUgaWYgYW55dGhpbmcgaW1wcm92ZXMuIFVzdWFsbHksIGxvdyBudW1iZXIgb2YgY2x1c3RlcnMgc3VnZ2VzdHMgbG93LWNvbXBsZXhpdHkgZGF0YSAoZWl0aGVyIGJpb2xvZ2ljYWwgb3IgdGVjaG5pY2FsIHJlYXNvbnMpLiBSZW1lbWJlciB0aGF0IHlvdSBjYW4gYWxzbyBsZWF2ZSBvdXQgYW1iaWVudCBSTkEgY29ycmVjdGlvbiB3aGVuIGRlYWxpbmcgbG93LWNvbXBsZXhpdHkgaWYgaGlnaGVyIFVNQVAgZGltZW5zaW9ucyBkbyBub3QgaW1wcm92ZSBhbnl0aGluZy4KICAtIFdpdGggdGhlIGVzdGltYXRlZCBjb250YW1pbmF0aW9uIGZyYWN0aW9uIGFuZCB0aGUgYmFja2dyb3VuZCBleHByZXNzaW9uIHByb2ZpbGUgYXQgb3VyIGRpc3Bvc2FsLCB0aGUgY29udGFtaW5hdGVkIGNvdW50cyBmb3IgZWFjaCBnZW5lIHdpdGhpbiBlYWNoIGNlbGwgY2FuIHRoZW4gYmUgY29ycmVjdGVkLgoKKiBLZWVwIGluIG1pbmQgdGhhdCB3b3JraW5nIHdpdGggdGhlIHJhdyBjb3VudHMgbWF0cml4IG9ubHkgd2lsbCBhdXRvbWF0aWNhbGx5IGZpbHRlciBjZWxscy9kcm9wbGV0cyB0aGF0IGhhdmUgbGVzcyB0aGFuIDEwMCBnZW5lcy4gVGhpcyBpcyBhIGxlc3MgYWdncmVzc2l2ZSBmaWx0ZXJpbmcgd2hlbiBjb21wYXJlZCB0byB1c2luZyB0aGUgZmlsdGVyZWQgY291bnRzIG1hdHJpeCB3aGVyZSBDZWxscmFuZ2VyIGZpbHRlcmVkIG91dCBjZWxscy9kcm9wbGV0cyB0aGF0IGNvbnRhaWVkIDw1MDAgVU1Jcy4gRm9yIHRoaXMgcmVhc29uLCBkbyBub3QgYmUgc2hvY2tlZCB0byBmaW5kIGhpZ2hlciBhbWJpZW50IFJOQSBjb250YW1pbmF0aW9uIHdoZW4gd29ya2luZyB3aXRoIHRoZSByYXcgY291bnRzLiBUaGUgZGF0YSB3aWxsIGJlIHN1Y2Nlc3NmdWxseSBjb3JyZWN0ZWQgbW9zdCBvZiB0aGUgdGltZSAodW5sZXNzIHlvdSBhcmUgZGVhbGluZyB3aXRoIG1hbnkgZGVncmFkZWQgUk5BcyBkdWUgdG8gZmFpbGVkIGV4cGVyaW1lbnQpLgoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogQ29udGFtaW5hdGlvbiBEZW5zaXR5IHBsb3QgKEZpcnN0IHBsb3QpOiAgIAotIFJlcHJlc2VudGluZyB0aGUgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIG9mIGVzdGltYXRlZCBjb250YW1pbmF0aW9uIGZyYWN0aW9uLiBUaGUgcHJvYmFiaWxpdHkgZGVuc2l0eSBpcyBjYWxjdWxhdGVkIGJ5IHRoZSBhZ2dyZWdhdGVkIHNldCBvZiBnZW5lcyBwZXIgY2VsbHMtY2x1c3RlciB0aGF0IGhhdmUgYmVlbiB1c2VkIHRvIGZpbmQgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24uIFRoZSBmaW5hbCBjb250YW1pbmF0aW9uIGZyYWN0aW9uIGlzIHRoZW4gYXNzaWduZWQgdG8gdGhlIG9uZSB0aGF0IG9jY3VycyB3aXRoIHRoZSBoaWdoZXN0IHByb2JhYmlsaXR5IChpbmRpY2F0ZWQgd2l0aCBhIHZlcnRpY2FsIHJlZCBsaW5lKS4gQSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gd2l0aCBhIGZsYXQgbGluZSAobm8gY2xlYXIgcGVhaykgaW5kaWNhdGVzIGZhaWx1cmUgb2YgU291cFggYXMgbm9uZSBvZiB0aGUgc2V0cyBvZiBnZW5lcyBoYXZlIGEgcHJlZmVycmVkIGNvbnRhbWluYXRpb24gZnJhY3Rpb24sIHdoaWxlIHRydWUgZXN0aW1hdGVzIGFyZSBtb3JlIGxpa2VseSB0byBoYXZlIHRoZSBzYW1lIHByb2JhYmlsaXR5LgoKKiBCYXJwbG90OgogIC0gUmVwcmVzZW50aW5nIHRoZSBwZXJjZW50YWdlIG9mIGFtYmllbnQgUk5BIGRldGVjdGVkIGFuZCByZW1vdmVkIGZyb20gdGhlIGRhdGEuIEEgY29udGFtaW5hdGlvbiBsZXZlbCBvZiBhcm91bmQgMTAlIGlzIHR5cGljYWwgZm9yIG5vbi1udWNsZWkgZnJlc2ggdGlzc3VlIHNhbXBsZS4KCiogQWZmZWN0ZWQgTWFya2VycyBTb3VwIE1hcmtlcnMgKFVNQVApOiAKICAtIFJlcHJlc2VudGluZyB0aGUgZXhwcmVzc2lvbiBvZiBtYXJrZXIgY2FuZGlkYXRlcyB0aGF0IHdlcmUgdXNlZCBmb3IgdGhlIGVzdGltYXRpb24gb2YgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gYW5kIHRoZWlyIGxldmVsIG9mIGNvcnJlY3Rpb24gKHByZSBhbmQgcG9zdCBTb3VwIGNvcnJlY3Rpb24pLiBCeSBkZWZhdWx0LCB0b3AgMyBtYXJrZXJzIGFyZSB1c2VkIGZvciBwbG90dGluZywgYnV0IHRoZSB1c2VyIGlzIHByb3ZpZGVkIHdpdGggdGhlIG9wdGlvbiB0byBjaG9vc2UgYW55dGhpbmcgYmV0d2VlbiAwLTEwMC4gCgoqIEFmZmVjdGVkIFVzZXIgR2VuZXMgKFVNQVApOiAKICAtIFJlcHJlc2VudGluZyB0aGUgZXhwcmVzc2lvbiBvZiB1c2VyLWRlZmluZWQgZ2VuZXMgYW5kIGxldmVsIG9mIGNvcnJlY3Rpb24uIEZvciB0aGlzIHRvIHdvcmsgdGhlIHVzZXIgbXVzdCBmaWxsIGluIHRoZSBnZW5lcyBvZiBpbnRlcmVzdCBpbiB0aGUgZ2VuZS50eHQgZmlsZS4KICAKKiBNb3N0IEFmZmVjdGVkIEdlbmVzIChVTUFQKTogCiAgLSBSZXByZXNlbnRpbmcgdGhlIGV4cHJlc3Npb24gb2YgbW9zdC1hZmZlY3RlZCBnZW5lcyBhbmQgbGV2ZWwgb2YgY29ycmVjdGlvbi4gQXMgdGhlIG1vc3QtYWZmZWN0ZWQgZ2VuZXMgYXJlIG5vdCBleHByZXNzZWQgYnkgbWFueSBjZWxscywgdGhlc2UgcGxvdHMgbWlnaHQgbm90IGJlIHZlcnkgcmVwcmVzZW50YXRpdmUuIFRoaXMgb3B0aW9uIGlzIHR1bmVkIG9mZiBieSBkZWZhdWx0LCBidXQgdGhlIHVzZXIgbWF5IHR1cm4gaXQgb24gYW5kIHNlbGVjdCB0aGUgbnVtYmVyIHBsb3RzLgoKKiBDb2xvcnMgaW4gdGhlIFVNQVAgcGxvdHM6CiAgLSBSZWQgZG90cyAtIHRoZSBnZW5lIGlzIHN0cm9uZ2x5IGNvcnJlY3RlZCBpbiB0aGUgY2VsbAogIC0gV2hpdGUgZG90cyAtIHRoZSBnZW5lIGlzIHdlYWtseSBjb3JyZWN0ZWQgaW4gdGhlIGNlbGwKICAtIEdyZXkgZG90cyAtIE5vdGhpbmcgaGFwcGVuZWQgdG8gdGhhdCBjZWxsCmBgYHtyIFNvdXB4LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD05LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIGVsaW1pbmF0ZXMgYW5kIGNvcnJlY3RzIGZvciBhbWJpZW50IFJOQSB1c2luZyBTb3VwWAojIC8vIEJhc2VkIG9uIHVzZXIgcGFyYW1ldGVycywgdGhlIGVmZmVjdCBvZiBhbWJpZW50IFJOQSBjb3JyZWN0aW9uIHdpbGwgYmUgZGlzcGxheWVkIGluIGEgVU1BUCBwcm9qZWN0aW9uCiMgLy8gQSBhbWJpZW50IFJOQSBjb3JyZWN0ZWQgcmF3IGNvdW50IG1hdHJpeCB3aWxsIGJlIHJldHVybmVkIGFuZCBzYXZlZCBvbiB1c2VyIGRlZmluZWQgcGF0aAojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCmlmIChsb3cuY29tcGxleGl0eSA9PSAieWVzIiAmIHN0cl9sZW5ndGgobG93LmNvbXBsZXhpdHkpICE9IDApIHsgIyBJZiB3ZSBoYXZlIGxvdyBjb21wbGV4aXR5IGRhdGEgb3Igd3JvbmcgcGFyYW1ldGVyIGdpdmVuLCB0aGVuIFNvdXBYIHdpbGwgYmUgc2tpcHBlZAogIHByaW50KCJDb3JyZWN0aW9uIGZvciBhbWJpZW50IFJOQSB3aWxsIG5vdCBiZSBjYXJyaWVkIG91dCIpCn0gZWxzZSB7CiAgaWYgKHN0cl9sZW5ndGgoY291bnRzX3BhdGhfcmF3KSAhPSAwKSB7ICAjIElmIHdlIGhhdmUgYSByYXcgY291bnQgbWF0cml4IGRhdGEgYW5kIGxvdy5jb21wbGV4aXR5IHBhcmFtZXRlciBpcyBub3QgZ2l2ZW4gb3Igbm8sIHRoZW4gU291cFggd2lsbCBydW4KICAgIHNvYmpfbGlzdF9maWx0ZXJlZCA8LSBsaXN0KCkgIyBtYWtlIGVtcHR5IGxpc3QgdG8gYXBwZW5kIFNldXJhdCBTb3VweCBjbGVhbmVkIFNldXJhdCBvYmplY3RzIGluIHRoZSBsb29wIGJlbG93IChvbmx5IGluIGNhc2Ugd2UgdXNlIGRpZmZlcmVudCBhcHByb3VjaCkKICAgIGZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc2FtcGxlX25hbWVzKSkgewogICAgICBzb2JqX2xpc3RbW2ldXVtbIm9yaWdpbmFsLmNvdW50cyJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BJGNvdW50cykgIyBrZWVwIG9yaWdpbmFsIGNvdW50IHRvIG1ha2UgY29tcGFyaXNvbiBmb3IgbGF0ZXIKICAgICAgIyBydW4gU291cHg6CiAgICAgIHNvdXBfY2hhbm5lbCA9IFNvdXBDaGFubmVsKGQxMHguZGF0YS5yYXdbW2ldXSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMpICMgY3JlYXRlIHNvdXAgY2hhbm5lbHMgYnkgcGFzc2luZyBpbiB0aGUgcmF3IDEwWCBtYXRyaXggYW5kIHRoZSBTZXVyYXQgY291bnRzIG1hdHJpeAogICAgICBzb3VwX2NoYW5uZWwgPSBzZXRDbHVzdGVycyhzb3VwX2NoYW5uZWwsIHNvYmpfbGlzdFtbaV1dJHNldXJhdF9jbHVzdGVycykgIyBXZSBzZXQgdGhlIGNsdXN0ZXJzIHByZXZpb3VzbHkgZm91bmQsIGFzIHRoZXNlIGNsdXN0ZXJzIGFyZSBlc3NlbnRpYWwgdG8gZmluZCBoaWdobHkgc3BlY2lmaWMgbWFya2VyIGdlbmVzLiAgIAogICAgICBzb3VwX2NoYW5uZWwgPSBhdXRvRXN0Q29udChzb3VwX2NoYW5uZWwsIGRvUGxvdD1UUlVFLCBwcmlvclJobyA9IDAuMDUsIHByaW9yUmhvU3RkRGV2ID0gMC4xLCByaG9NYXhGRFIgPSAwLjIsIGZvcmNlQWNjZXB0PVRSVUUpICMgZXN0aW1hdGUgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gdXNpbmcgbWFya2VycyBmcm9tIGNsdXN0ZXJzCiAgICAgIG91dCA9IGFkanVzdENvdW50cyhzb3VwX2NoYW5uZWwsIHJvdW5kVG9JbnQgPSBUUlVFKSAjIEZyb20gdGhlIHNvdXAgY2hhbm5lbCB3ZSBnZXQgdGhlIGFkanVzdGVkIGNvdW50cyBtYXRyaXggYW5kIHJvdW5kIGl0IHRvIHRoZSBuZWFyZXN0IGludGVnZXIuLi4uLi4uLiAjIyMjIyMjIyMjIFNBRkUgVEhFIE9VVFBVVFMgT0YgQU1CSUVOVCBSTkEKICAKICAgICAgIyBTYXZlIHRoZSBBbWJpZW50IFJOQSBjb3JyZWN0ZWQgTWF0cml4CiAgICAgIGlmIChkaXIuZXhpc3RzKGZpbGUucGF0aChwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMiLCBzZXAgPSAiIiksIHNlcCA9ICIvIikpKSkgewogICAgICAgIHdyaXRlMTB4Q291bnRzKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cy9Tb3VwQ29ycmVjdGVkQ291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpLCBvdXQsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSksIHJlY3Vyc2l2ZSA9IFRSVUUpCiAgICAgICAgICB3cml0ZTEweENvdW50cyhwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMvU291cENvcnJlY3RlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgb3V0LCB2ZXJzaW9uID0gIjMiLCBvdmVyd3JpdGUgPSBUUlVFKQogICAgICAgICAgfQogIAogICAgICAjIHVwZGF0ZSB0aGUgUk5BIGNvdW50cyB3aXRoIHRoZSBzb3VwIGNvcnJlY3RlZCBtYXRyaXghISEKICAgICAgIyBOT1RFIHRoYXQgd2UgZG8gdGhpcyB0d2ljZSwgZm9yIHR3byBzZXBhcmF0ZSBzbG90cyAoZXZlbiB0aG91Z2ggaXQgaXMgdGhlIHNhbWUpLCBiZWNhdXNlIHRoZSBkZXZlbG9wZXJzIG9mIFNldXJhdF92NSB0aG91Z2h0IGl0IHdhcyBjb29sIHRvIEZVQ0sgdGhpbmdzIHVwIQogICAgICAjIElmIHlvdSBhcmUgdXBkYXRpbmcgdGhlIFNldXJhdCBwYWNrYWdlIGluIHRoZSBmdXR1cmUsIHBsZWFzZSBtYWtlIHN1cmUgdGhlIHR3byBsaW5lIGJlbG93IGFyZSBjb21wYXRpYmxlLiBJZiBub3QsIHRoZW4gZ2V0IHJlYWR5IGZvciBzb21lIEZVQ0tJTkcgc2xlZXBsZXNzIG5pZ2h0cy4uLgogICAgICBzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BJGNvdW50cyA8LSBvdXQgCiAgICAgICNzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BQGxheWVycyRjb3VudHMgPC0gb3V0ICMgZm9yICBzdWVyYXR2NQoKICAgICAgIyBBZGQgdGhlIGNsdXN0ZXJpbmcgY29vcmRpbmF0ZXMgb2Ygb3VyIFNldXJhdCBvYmplY3RzIHRvIHRoZSBTb3VwIGNoYW5uZWwKICAgICAgVU1BUDEgPC0gZGF0YS5mcmFtZShzb2JqX2xpc3RbW2ldXUByZWR1Y3Rpb25zW1sidW1hcCJdXUBjZWxsLmVtYmVkZGluZ3MpWyAsIDFdICMgZXh0cmFjdCB0aGUgVU1BUCBjb29yZGluYXRlcyBmcm9tIFNldXJhdCBvYmplY3QKICAgICAgVU1BUDIgPC0gZGF0YS5mcmFtZShzb2JqX2xpc3RbW2ldXUByZWR1Y3Rpb25zW1sidW1hcCJdXUBjZWxsLmVtYmVkZGluZ3MpWyAsIDJdCiAgICAgIHNvdXBfY2hhbm5lbCRtZXRhRGF0YVtbIlVNQVAxIl1dIDwtIFVNQVAxICMgQXBwZW5kIHRoZSBVTUFQIGNvb3JkaW5hdGVzIHRvIHRoZSBzb3VwX2NoYW5uZWwkbWV0YURhdGEKICAgICAgc291cF9jaGFubmVsJG1ldGFEYXRhW1siVU1BUDIiXV0gPC0gVU1BUDIKICAgICAgc291cF9jaGFubmVsW1siRFIiXV0gPC0gdW5saXN0KGMoIlVNQVAxIiwgIlVNQVAyIikpICMgYWRkIGEgKGNoYXJhY3RlciBbMl0pIG9mICJVTUFQMSIiVU1BUDIiIHRvIHRoZSBzb3VwX2NoYW5uZWwKICAgICAgc291cF9tZXRhZGF0YSA8LSBzb3VwX2NoYW5uZWwkbWV0YURhdGEgIyBzb3VwIGNoYW5uZWwgbWV0YWRhdGEgZGF0YSBzYXZpbmcKICAKICAgICAgIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2Ugb2YgY29udGFtaW5hdGVkIFJOQSAoVU1JKSByZW1vdmUKICAgICAgcGVyY2VudGFnZV9jb250YW1pbmF0aW9uIDwtIHBhc3RlKCJQZXJjZW50YWdlIG9mIEFtYmllbnQgUk5BIChVTUkpIHJlbW92ZWQ6IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMiksIHNlcCA9ICIgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdKSkgCiAgICAgIHByaW50KHBlcmNlbnRhZ2VfY29udGFtaW5hdGlvbikKICAKICAgICAgIyBNYWtlIGRhdGEgZnJhbWUgb2YgYW1iaWVudCBSTkEgY29udGFtaW5hdGlvbiBsZXZlbHMgYW5kIG1ha2UgYmFycGxvdAogICAgICBkYXRhLmZyYW1lLmNvbnQgPC0gZGF0YS5mcmFtZShzYW1wbGVfbmFtZXMsIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMikpCiAgICAgICMgcGxvdCBiYXJzCiAgICAgIFMxIDwtIGdncGxvdChkYXRhLmZyYW1lLmNvbnQsIGFlcyh4ID0gZmFjdG9yKHNhbXBsZV9uYW1lcywgbGV2ZWxzID0gc2FtcGxlX25hbWVzKSwgeSA9IHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMikpKSArIAogICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGFscGhhID0gMC41LCBjb2xvdXIgPSAiYmxhY2siLCB3aWR0aCA9IDAuNSkgKyAKICAgICAgICB5bGltKDAsIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCArIDUpKSArIAogICAgICAgIGdlb21fdGV4dChsYWJlbCA9IHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMiksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSx2anVzdCA9IC0wLjUsIHNpemUgPSA0KSArICMgdmFsdWUgYWJvdmUgYmFyCiAgICAgICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xKSArIAogICAgICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArCiAgICAgICAgdGhlbWVfYncoKSArIAogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHNpemUgPSA5LjUpKSArIAogICAgICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICsgCiAgICAgICAgbGFicyh4PSIiLCB5PSJBbWJpZW50IFJOQSBSZW1vdmVkICglKSIpICsgc2NhbGVfZmlsbF9ncmV5KCkgKwogICAgICAgIHRoZW1lKGFzcGVjdC5yYXRpbyA9IDUuNSkgIyArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjc1KSkKICAgICAgcHJpbnQoUzEpCiAgCiAgICAgICMgQW5hbHl6ZSBvdXRwdXQgYW5kIHBsb3QgbWFya2VycywgcmFuZG9tIGdlbmVzLCBtb3N0IGFmZmVjdGVkLCBvciB1c2VyIGdpdmVuIG1hcmtlcnM6CiAgICAgICMgQnV0IGZpcnN0IHdlIHNldHVwIHRoZSBudW1iZXIgb2YgcGxvdHMgZGVmaW5lZCBieSAgdXNlciBvcHRpb25zIG9yIGRlZmF1bHQKICAgICAgaWYgKGlzLm5hKG4ubWFya2Vycy5nZW5lcykgPT0gVFJVRSkgewogICAgICAgIG1hcmtlcnNfYnlfc291cCA8LSBzb3VwX2NoYW5uZWxbWyJmaXQiXV1bWyJtYXJrZXJzVXNlZCJdXVtbImdlbmUiXV1bMTozXSAjIDMgbWFya2VycyB1c2VkIGJ5IGJ5IGRlZmF1bHQKICAgICAgfSBlbHNlIHsKICAgICAgICBtYXJrZXJzX2J5X3NvdXAgPC0gc291cF9jaGFubmVsW1siZml0Il1dW1sibWFya2Vyc1VzZWQiXV1bWyJnZW5lIl1dWzE6bi5tYXJrZXJzLmdlbmVzXSAjIG9yIHVzZXIgcGFyYW1ldGVyCiAgICAgIH0KICAgICAgaWYgKGlzLm5hKG4uaGlnaGx5X2FmZmVjdGVkLmdlbmVzKSA9PSBUUlVFKSB7CiAgICAgICAgZXhwX2JlZm9yZS5zb3VwIDwtIG5hbWVzKHRhaWwoc29ydCgocm93U3Vtcyhzb3VwX2NoYW5uZWwkdG9jID4gMCkgLSByb3dTdW1zKG91dCA+IDApKS9yb3dTdW1zKHNvdXBfY2hhbm5lbCR0b2MgPiAwKSksIG4gPSAwKSkgCiAgICAgIH0gZWxzZSB7CiAgICAgICAgZXhwX2JlZm9yZS5zb3VwIDwtIG5hbWVzKHRhaWwoc29ydCgocm93U3Vtcyhzb3VwX2NoYW5uZWwkdG9jID4gMCkgLSByb3dTdW1zKG91dCA+IDApKS9yb3dTdW1zKHNvdXBfY2hhbm5lbCR0b2MgPiAwKSksIG4gPSBuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcykpIAogICAgICAgIH0KICAgICAgCiAgICAgICMgcHJpbnQoZXhwX2JlZm9yZS5zb3VwKQogICAgICAjIHJhZG5vbV9nZW5lcyA8LSBzYW1wbGUoeCA9IHJvd25hbWVzKGRhdGEuZnJhbWUoc291cF9jaGFubmVsJHRvYykpLCBzaXplID0gMTAsIHJlcGxhY2UgPSBGQUxTRSkgIyA0IFJhbmRvbWx5IHNlbGVjdGVkIGdlbmVzIHRvIGNoZWNrIGFmZmVjdGlvbiBhZnRlciBjb3JyZWN0aW9uCgogICAgICAjIHBsb3QgdGhlIG1vc3QgbWFya2VyIGdlbmVzIGJlZm9yZSBhbmQgYWZ0ZXIgY29ycmVjdGlvbjoKICAgICAgaWYgKGxlbmd0aChjYW5vbmljYWxfbWFya2VycykgPiAwIHwgKG4ubWFya2Vycy5nZW5lcyA+IDAgJiBsZW5ndGgoY2Fub25pY2FsX21hcmtlcnMpID4gMCkpIHsKICAgICAgICBpZiAobi5tYXJrZXJzLmdlbmVzID4gMCAmIGlzLm5hKG4ubWFya2Vycy5nZW5lcykgPT0gRkFMU0UpIHsKICAgICAgICAgIGZvciAoaiBpbiBtYXJrZXJzX2J5X3NvdXApewogICAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICAgICAjIFBsb3QKICAgICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIkFzc3VtaW5nIEFsbCBDZWxscyBhcmUgU291cCIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICBwcmludChwbG90Q2hhbmdlTWFwKHNvdXBfY2hhbm5lbCwgb3V0LCBqLCBwb2ludFNpemUgPSAxLjUpICsgCiAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgeyAjIEVoLCBzb21lIHNsb3BweSBjb2Rpbmcgd2l0aCBlbHNlIGFuZCBubyBhcmd1bWVudAogICAgICAgICAgICB9CiAgICAgICAgZm9yIChqIGluIGNhbm9uaWNhbF9tYXJrZXJzKSB7CiAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdICMgYWRkIHRoZSBnZW5lcyB0byBiZSBhbmFseXplZCB0b3QgdGhlIG1ldGFkYXRhIGNvbHVtbnMKICAgICAgICAgICAjIGlmIHdlIGFzc3VtZWQgYWxsIGNlbGxzIHdlcmUgbm90aGluZyBidXQgc291cCwgd2hpY2ggY2VsbHMgc3RpbGwgc2hvdyBoaWdoZXIgdGhhbiBleHBlY3RlZCBleHByZXNzaW9uIGZvciB0aGUgZ2VuZSAoVFJVRSA9IGV4cHJlc3Npb24gbGV2ZWxzIGhpZ2hlciB0aGFuIGV4cGVjdGVkIGlmIGNlbGwgd2FzIGp1c3Qgc291cCwgc28gbGlrZWx5IHJlYWwgZXhwcmVzc2lvbikuIFRoaXMganVzdCBnaXZlcyB1cyBhbiBpZGVhIG9mIHNvdXAgZXhwcmVzc2lvbiwgdGhpcyBpcyBOT1QgYSBmb3JtYWwgYW5hbHlzaXMgdXNlZCBmb3IgcmVtb3ZpbmcgdGhlIHNvdXAgUk5BLgogICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiRXhwcmVzc2lvbmcgb2Y6ICIsIHBhc3RlKGosICJBc3N1bWluZyBBbGwgQ2VsbHMgYXJlIFNvdXAiLCBzZXAgPSAiIChtYXJrZXIpIC0gIikpLCBzdWJ0aXRsZSA9IHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdKSArIAogICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgIyBDaGFuZ2UgaW4gZXhwcmVzc2lvbiBhZnRlciBTb3VwIGNvcnJlY3Rpb24KICAgICAgICAgIHByaW50KHBsb3RDaGFuZ2VNYXAoc291cF9jaGFubmVsLCBvdXQsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKG1hcmtlcikgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikpCiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsgIyBpZiBtYXJrZXJzIGFyZSBub3QgcHJvdmlkZWQgYnkgdGhlIHVzZXIsIHRoZW4gcGxvdCB0aGUgdG9wIDUgbWFya2VyIGdlbmVzIHVzZWQgYnkgU291cFgKICAgICAgICAgIGZvciAoaiBpbiBtYXJrZXJzX2J5X3NvdXApewogICAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICAgICAjIFBsb3QKICAgICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIkFzc3VtaW5nIEFsbCBDZWxscyBhcmUgU291cCIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICBwcmludChwbG90Q2hhbmdlTWFwKHNvdXBfY2hhbm5lbCwgb3V0LCBqLCBwb2ludFNpemUgPSAxLjUpICsgCiAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgCiAgICAgICMgcGxvdCB0aGUgbW9zdCBhZmZlY3RlZCBnZW5lcyBiZWZvcmUgYW5kIGFmdGVyIGNvcnJlY3Rpb24gCiAgICAgIGZvciAoaiBpbiBleHBfYmVmb3JlLnNvdXApIHsKICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICNnZ3Bsb3Qoc291cF9tZXRhZGF0YSwgYWVzKFVNQVAxLCBVTUFQMikpICsgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gQ0QzRSA+IDApLCBzaXplPTAuMikgKyBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIlByZSBTb3VwIENvcnJlY3Rpb24iLCBzZXAgPSAiIC0gIikpLCBzdWJ0aXRsZSA9IHNvYmpfbGlzdFtbMl1dQG1ldGEuZGF0YVsxLDFdKSArIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikKICAgICAgICBwcmludChwbG90TWFya2VyTWFwKHNvdXBfY2hhbm5lbCwgaiwgcG9pbnRTaXplID0gMSkgKyAKICAgICAgICAgICAgICAgIGdndGl0bGUocGFzdGUoIkV4cHJlc3Npb25nIG9mOiAiLCBwYXN0ZShqLCAiQXNzdW1pbmcgQWxsIENlbGxzIGFyZSBTb3VwIiwgc2VwID0gIiAoTW9zdCBhZmZlY3RlZCkgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgIHByaW50KHBsb3RDaGFuZ2VNYXAoc291cF9jaGFubmVsLCBvdXQsIGopICsgCiAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJDaGFuZ2UgaW4gRXhwcmVzc2lvbiBvZjogIiwgcGFzdGUoaiwgIlBvc3QgU291cCBDb3JyZWN0aW9uIiwgc2VwID0gIiAoTW9zdCBhZmZlY3RlZCkgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgIH0KICAgIH0KICB9IGVsc2UgeyAjIGVsc2Ugd2Ugbm90IHJ1biBzb3VweCBpZiB3ZSBkbyBub3QgaGF2ZSBhIHJhdyBjb3VudCBtYXRyaXggZm9yIHRoZSBjYWxjdWxhdGlvbiBvZiBhbWJpZW50IFJOQQogICAgcHJpbnQoIkR1ZSB0byBsYWNrIG9mIHJhdyBjb3VudCBtYXRyaXgsIGNvcnJlY3Rpb24gZm9yIGFtYmllbnQgUk5BIHdpbGwgbm90IGJlIGNhcnJpZWQgb3V0IikKICAgIH0KICB9CmBgYAoKIyMjIyBFeHRlbnNpdmUgZmlsdGVyaW5nICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBCeSBkZWZhdWx0LCB3ZSBhdXRvbWF0aWNhbGx5IGZpbHRlciBvdXQgY2VsbHMgd2l0aCBhIHBlcmNlbnRhZ2Ugb2YgTVQgcmVhZHMgYWJvdmUgMTAlLCB3aXRoIGdlbmUgYW5kIHRyYW5zY3JpcHQgY291bnRzIGJlbG93IHRoZSAyJSBxdWFudGlsZSBhcyBhIGxvd2VyIGxpbWl0LiBObyBmaWx0ZXJpbmcgaXMgYXBwbGllZCBvbiB0aGUgaGlnaGVyIGxpbWl0IGFzIHRoZXNlIGNlbGxzIGNvdWxkIHJlcHJlc2VudCBkb3VibGV0cyB0aGF0IHdlIHdhbnQgdG8gY2xhc3NpZnkgYnkgRG91YmxldEZpbmRlciBpbnN0ZWFkIG9mIHJlbW92aW5nIHRoZW0gYnkgZm9yY2UuIEhvd2V2ZXIsIGlmIHRoZSB1c2VyIGhhcyBwcmlvciBrbm93bGVkZ2Ugb24gdGhlIGRhdGFzZXQsIGZpbHRlcmluZyBjYW4gYWxzbyBiZSBhcHBsaWVkIGJ5IHVzZXItZGVmaW5lZCBjdXRvZmYgdmFsdWVzIGZvciB0aGUgbnVtYmVyIG9mIGdlbmVzLCB0cmFuc2NyaXB0cyBhbmQgcGVyY2VudGFnZSBvZiBNVCByZWFkcy4gQWRkaXRpb25hbGx5LCB0aGUgdXNlciBtYXkgYWxzbyBhZGp1c3QgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFudGlsZXMgZm9yIHRoZSBwYXJhbWV0ZXJzIG1lbnRpb25lZCBhYm92ZS4gSXQgaXMgaW1wb3J0YW50IHRvIGNvbnNpZGVyIHRoYXQgYnkgcmVtb3ZpbmcgY2VsbCBpbiB0aGUgdXBwZXIgbGltaXQgYnkgdXNlci1kZWZpbmVkIGN1dG9mZiB2YWx1ZXMgb3IgcXVhbnRpbGVzLCB0aGVyZSBpcyBhIGdvb2QgY2hhbmNlIHRoYXQgdHJ1ZSBkb3VibGV0cyBhcmUgYmVpbmcgcmVtb3ZlZCBiZWZvcmUgaWRlbnRpZmllZCBpbiBhbiBhbGdvcml0aG1pYyBmYXNoaW9uLgoKKiBOb3RlIHRoYXQgb3VyIGRlZmF1bHQgcGFyYW1ldGVycyBoYXZlIGJlZW4gcGVyZm9ybWluZyB3ZWxsIGluIGhpZ2ggY29tcGxleGl0eSAocG9yY2luZSBpbGV1bSBhbmQgY29sb24gdGlzc3VlLCB3aXRoIGltbXVuZSkgYW5kIGxvdyBjb21wbGV4aXR5IGRhdGEgKHBvcmNpbmUgaWxldW0gb3JnYW5vaWQpIHdpdGhvdXQgbG9vc2luZyBtYW55IGNlbGwtdHlwZXMgKGluY2x1ZGluZyBzb21lIHJhcmUgaW1tdW5lIGNlbGxzIHdpdGggbG93IG51bWJlciBvZiBnZW5lcy90cmFuc2NyaXB0cykuCgojIyMjIyBSZXN1bHRzOiAjIyMjIwoKKiBOb3cgdGFrZSBhIGxvb2sgaW4gdGhlIGNodW5rIGJlbG93Li4uIGhvdyBtYW55IGNlbGxzIGRvIHlvdSBoYXZlPyBJcyBpdCBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gYmVmb3JlPwogIC0gKFRoZSBjZWxscyBhcmUgY2FsbGVkICdzYW1wbGVzJykuCiAgLSAoSWdub3JlIHRoZSBpbmZsYXRlZCBudW1iZXIgb2YgJ2ZlYXV0dXJlcycuIFRoZXNlIGFyZSB0aGUgbnVtYmVyIG9mIGdlbmVzIGZyb20gdHdvIGFzc2F5cyBpbiBTZXVyYXQpLgpgYGB7ciBkYXRhIGZpbHRlcmluZywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTIsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcGVyZm9ybXMgYW4gZXh0ZW5zaXZlIGZpbHRlcmluZyBiYXNlZCBvbiB1c2VyIHBhcmFtZXRlcnMgKG9yIGRlZmF1bHQgaWYgbm90IHNwZWNpZmllZCkKIyAvLyBuRmVhdHVyZV9STkEgKG5HZW5lcyksIG5Db3VudF9STkEgKG5VTUlzKSBhbmQgTVQgcGVyY2VudGFnZSB3aWxsIGJlIGNvbnNpZGVyZWQKIyAvLyBCeSBkZWZhdWx0IDItOTglIHF1YW50aWxlIGFyZSBjb25zaWRlcmVkIGZvciB0aGUgcGFyYW1ldGVycyBtZW50aW9uZWQgYWJvdmUgd2l0aCBwZXJjZW50Lm10IDwgMTAKIyAvLyBDZWxsIHdpbGwgYmUgcmUtY2x1c3RlcmVkIGluIGNhc2UgdXNlciBkZWZpbmVkIHBhcmFtZXRlcnMgYXJlIHRvbyBleHRyZW1lIChyZXN1bHRpbmcgaW4gbG9zcyBvZiBtYW55IGNlbGxzKQojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIGZpbHRlcnMgYW5kIHJldHVybnMgYSBjbGVhbmVkIHVwIFNldXJhdCBvYmplY3QKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKZXh0X2ZpbHRlcmluZyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgaWYgKGlzLm5hKGZlYXR1cmVMT1cpICE9IFRSVUUgfCBpcy5uYShjb3VudExPVykgIT0gVFJVRSB8IGlzLm5hKGZlYXR1cmVISUdIKSAhPSBUUlVFIHwgaXMubmEoY291bnRISUdIKSAhPSBUUlVFKSB7ICMgd2UgZXhjbHVkZSBtdC5Db24gYmVjYXVzZSB0aGlzIHBhcmFtZXRlciBhbHdheXMgY29udGFpbnMgYSB2YWx1ZQogICAgaWYgKGZlYXR1cmVMT1cgPj0gMCAmIGZlYXR1cmVMT1cgPD0gbWF4KHNvYmpbWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BKSAmIGlzLm5hKGZlYXR1cmVMT1cpID09IEZBTFNFKSB7CiAgICAgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+PSBmZWF0dXJlTE9XKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoY291bnRMT1cgPj0gMCAmIGNvdW50TE9XIDw9IG1heChzb2JqW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BKSAmIGlzLm5hKGNvdW50TE9XKSA9PSBGQUxTRSkgewogICAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuQ291bnRfUk5BID49IGNvdW50TE9XKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoZmVhdHVyZUhJR0ggPj0gMCAmIGZlYXR1cmVISUdIID49IG1pbihzb2JqW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSkgJiBpcy5uYShmZWF0dXJlSElHSCkgPT0gRkFMU0UpIHsKICAgICAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BIDw9IGZlYXR1cmVISUdIKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoY291bnRISUdIID49IDAgJiBjb3VudEhJR0ggPj0gbWluKHNvYmpbWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEpICYgaXMubmEoY291bnRISUdIKSA9PSBGQUxTRSkgewogICAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuQ291bnRfUk5BIDw9IGNvdW50SElHSCkgCiAgICAgIH0gZWxzZSB7IH0KICAgIGlmIChtdC5Db24gPj0gMCAmIG10LkNvbiA8PSBtYXgoc29ialtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgJiBpcy5uYShtdC5Db24pID09IEZBTFNFKSB7CiAgICAgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IHBlcmNlbnQubXQgPD0gaWYgKG10LkNvbiA+PSAwICYgbXQuQ29uIDw9IG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAmIGlzLm5hKG10LkNvbikgPT0gRkFMU0Upe210LkNvbiA9IG10LkNvbn1lbHNle210LkNvbiA9IDEwfSkgCiAgICAgIH0gZWxzZSB7IH0KICB9IGVsc2UgeyAKICAgICMgRWxzZSBpZiB1c2VyIGlucHV0IG5vdCBzcGVjaWZpZWQKICAgIG1pbkNvdj0xMDAwICMgaWYgYSBzYW1wbGUgaGFzIGEgZ29vZCBjb3ZlcmFnZSAoPj1taW5Db3YpLCB0aGVuIGRvbid0IHNldCBhIGxvd2VyIHRocmVzaG9sZCBmb3IgbkNvdW50LCBpdCdzIGFscmVhZHkgcHJldHR5IGdvb2QuIAogICAgaWYgKG1pbihzb2JqJG5Db3VudF9STkEpID49IG1pbkNvdikgeyAgIyBpZiBtaW5pbXVtIFVNSSBjb3VudCBpcyA+PSAxMDAwCiAgICAgIGNvdW50TE9XID0gbWluKHNvYmokbkNvdW50X1JOQSkgICMgdGhlbiwgc2V0IHRvIGxvd2VzdCBuQ291bnQgaWYgd2UgaGF2ZSBnb29kIGNvdmVyYWdlCiAgICAgIH0gZWxzZSB7ICMgT3RoZXJ3aXNlIHVzZSB0aGUgcXVhbnRpbGUgcnVsZQogICAgICAgIGNvdW50TE9XID0gcXVhbnRpbGUoc29iaiRuQ291bnRfUk5BLCBwcm9iPWlmIChVTUkucXVhbnRpbGUubG93ID49IDAgJiBVTUkucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUubG93KSA9PSBGQUxTRSl7CiAgICAgICAgICBVTUkucXVhbnRpbGUubG93ID0gVU1JLnF1YW50aWxlLmxvd31lbHNle1VNSS5xdWFudGlsZS5sb3cgPSAwLjAyfSkgCiAgICAgICAgfSAjIGVsc2Ugc2V0IHRvIDIlIHF1YW50aWxlCiAgICBjb3VudEhJR0ggPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXsKICAgICAgVU1JLnF1YW50aWxlLmhpZ2ggPSBVTUkucXVhbnRpbGUuaGlnaH1lbHNle1VNSS5xdWFudGlsZS5oaWdoID0gMS4wfSkgIyBTZXQgb24gMS4wIGJlIGRlZmF1bHQsIGJlY2F1c2UgaXQgY24gaW50ZXJmZXJlIHdpdGggRG91YmxldEZpbmRlciwgYnV0IDAuOTggaXMgcmVhc29uYWJsZSBpcyB1c2VyIGxpa2VzIHNwZWNpZnkgdGhhdC4KICAgIGZlYXR1cmVMT1cgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZihmZWF0dXJlLnF1YW50aWxlLmxvdyA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5sb3cgPD0gMSAmIGlzLm5hKGZlYXR1cmUucXVhbnRpbGUubG93KSA9PSBGQUxTRSl7CiAgICAgIGZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSAKICAgIGZlYXR1cmVISUdIID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXsKICAgICAgZmVhdHVyZS5xdWFudGlsZS5oaWdoID0gZmVhdHVyZS5xdWFudGlsZS5oaWdofWVsc2V7ZmVhdHVyZS5xdWFudGlsZS5oaWdoID0gMS4wfSkgCiAgICAjIGZpbHRlciBiYXNlZCBvbiBvbiB2aXN1YWxpemF0aW9uIGFuIHBhcmFtZXRlcnMgYWJvdmUuCiAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuRmVhdHVyZV9STkEgPj0gZmVhdHVyZUxPVyAmIG5GZWF0dXJlX1JOQSA8PSBmZWF0dXJlSElHSCAmIG5Db3VudF9STkEgPj0gY291bnRMT1cgJiBuQ291bnRfUk5BIDw9IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPD0gaWYgKG10LkNvbiA+PSAwICYgbXQuQ29uIDw9IG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAmIGlzLm5hKG10LkNvbikgPT0gRkFMU0Upe210LkNvbiA9IG10LkNvbn1lbHNle210LkNvbiA9IDEwfSkKICAgICMgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gZmVhdHVyZUxPVyAmIG5Db3VudF9STkEgPiBjb3VudExPVyAmIG5Db3VudF9STkEgPCBjb3VudEhJR0ggJiBuRmVhdHVyZV9STkEgPCBmZWF0dXJlSElHSCAmIHBlcmNlbnQubXQgPCAxMCkgIyBVU0UgVEhJUyBMSU5FIElGIElOQ0xVRElORyBmZWF0dXJlSElHSCBhbmQgY291bnRMT1cgcGFyYW1ldGVycwogIAogICAgIyBBZnRlciBpbml0aWFsIGZpbHRlcmluZywgd2UgY291bGQgc2F2ZSBvbmUgYmFja3VwIGluIG9yZGVyIHRvIGFwcGx5IGFtYmllbnQgYW5kIG11bHRpcGxldCByZW1vdmFsIG9uIHRoaXMgb2JqZWN0CiAgICAjIHNvYmouZmlsdGVyZWQgPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cgJiBuQ291bnRfUk5BID4gY291bnRMT1cgICYgbkNvdW50X1JOQSA8IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPCAxMCkKICB9CiAgcmV0dXJuKHNvYmopCiAgfQogIAojIEFwcGx5IGZ1bmN0aW9uIGFuZCBwcmludCB0aGUgb3V0cHV0IGZvciBjb250cm9sCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBleHRfZmlsdGVyaW5nKQpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBwcmludChzb2JqX2xpc3RbaV0pCn0KCgoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFRFU1RJTkcgQ09ERSBQSVBFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKI2lmIChmZWF0dXJlTE9XID4gMCAmIGlzLm5hKGZlYXR1cmVMT1cpID09IEZBTFNFKSB7CiMgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cpCiN9IGVsc2UgeyB9CiNpZiAoY291bnRMT1cgPiAwICYgaXMubmEoY291bnRMT1cpID09IEZBTFNFKSB7CiMgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5Db3VudF9STkEgPiBjb3VudExPVykKI30gZWxzZSB7IH0KI2lmIChmZWF0dXJlSElHSCA+IDAgJiBpcy5uYShmZWF0dXJlSElHSCkgPT0gRkFMU0UpIHsKIyAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BIDwgZmVhdHVyZUhJR0gpCiN9IGVsc2UgeyB9CiNpZiAoY291bnRISUdIID4gMCAmIGlzLm5hKGNvdW50SElHSCkgPT0gRkFMU0UpIHsKIyAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkNvdW50X1JOQSA8IGNvdW50SElHSCkgCiN9IGVsc2UgeyB9CiNpZiAocGVyY2VudC5tdCA+IDAgJiBpcy5uYShwZXJjZW50Lm10KSA9PSBGQUxTRSkgewojICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBwZXJjZW50Lm10IDwgbXQuQ29uKSAKI30gZWxzZSB7IH0KCiNybShzb2JqMSkKCiNxdWFudGlsZShzb2JqX2xpc3RbWzFdXSRuRmVhdHVyZV9STkEsIHByb2I9MC4wMikgCiNxdWFudGlsZShzb2JqX2xpc3RbWzFdXSRuQ291bnRfUk5BLCBwcm9iPTAuMDIpCgojbWF4KHNvYmpfbGlzdFtbaV1dW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KQojbWF4KHNvYmpfbGlzdFtbaV1dW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BKSAKI21heChzb2JqX2xpc3RbW2ldXVtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEpCiNtaW4oc29ial9saXN0W1tpXV1bWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEpIAojbWluKHNvYmpfbGlzdFtbaV1dW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSkKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFRFU1RJTkcgQ09ERSBGT1IgU0lOR0xFVFMgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiNtaW5Db3Y9MTAwMCAjaWYgYSBzYW1wbGUgaGFzIGEgZ29vZCBjb3ZlcmFnZSAoPj1taW5Db3YpLCB0aGVuIGRvbid0IHNldCBhIGxvd2VyIHRocmVzb2xkIGZvciBuQ291bnQsIGl0J3MgYWxyZWFkeSBwcmV0dHkgZ29vZC4gCiNpZiAobWluKHNvYmokbkNvdW50X1JOQSkgPj0gbWluQ292KSAgIyBpZiBtaW5pbXVtIFVNSSBjb3VudCBpcyA+PSAxMDAwCiMgICAgeyBjb3VudExPVyA9IG1pbihzb2JqJG5Db3VudF9STkEpICAjIHRoZW4sIHNldCB0byBsb3dlc3QgbkNvdW50IGlmIHdlIGhhdmUgZ29vZCBjb3ZlcmFnZQojICB9IGVsc2UgeyBjb3VudExPVz1xdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9YygwLjAyKSkgfSAjIGVsc2Ugc2V0IHRvIDIlIHF1YW50aWxlCiNjb3VudEhJR0ggPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9MC45OSkgIyBhbmQgdG8gOTklIHF1YW50aWxlIGZvciB0aGUgdXBwZXIgY291bnQsIGJlY2F1c2UgdGhlc2UgaGlnaCBVTUktY291bnQgY2VsbHMgd2lsbCBhbHNvIGJlIGZpbHRlcmVkIG91dCBieSB0aGUgRG91YmxldEZpbmRlciBvciByZWR1Y2VkIHdoZW4gYWRqdXN0aW5nIGZvciBhbWJpZW50IFJOQSBjb3VudHMKI2ZlYXR1cmVMT1cgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjAyKSAgIyBtaW5pbXVtIG51bWJlciBvZiBnZW5lcyBzZXQgdG8gMiUgcXVhbnRpbGUKI2ZlYXR1cmVISUdIID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9MC45OSkKIyBmaWx0ZXIgYmFzZWQgb24gb24gdmlzdWFsaXphdGlvbiBhbiBwYXJhbWV0ZXJzIGFib3ZlLgojc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gZmVhdHVyZUxPVyAmIG5Db3VudF9STkEgPiBjb3VudExPVyAgJiBuQ291bnRfUk5BIDwgY291bnRISUdIICYgcGVyY2VudC5tdCA8IDEwKQojc29iagoKIyBBZnRlciBpbml0aWFsIGZpbHRlcmluZywgd2Ugd2lsbCBzYXZlIG9uZSBiYWNrdXAgaW4gb3JkZXIgdG8gYXBwbHkgYW1iaWVudCBhbmQgbXVsdGlwbGV0IHJlbW92YWwgb24gdGhpcyBvYmplY3QKI3NvYmouZmlsdGVyZWQgPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cgJiBuQ291bnRfUk5BID4gY291bnRMT1cgICYgbkNvdW50X1JOQSA8IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPCAxMCkKYGBgCgojIyMjIE11bHRpcGxldCBSZW1vdmFsICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBUaGUgRG91YmxldEZpbmRlciBhbGdvcml0aG0gZmlyc3QgZ2VuZXJhdGVzIGFydGlmaWNpYWwgZG91YmxldHMgYnkgcmFuZG9tbHkgbWVyZ2luZyBkaWZmZXJlbnQgY2VsbHMgZnJvbSB0aGUgZGF0YS4gSW4gdG90YWwsIG9uZSBhcnRpZmljaWFsIGRvdWJsZXQgaXMgZ2VuZXJhdGVkIHBlciBmb3VyIGNlbGxzLiBXZSBhcmUgZXNzZW50aWFsbHkgY3JlYXRpbmcgYSBuZXcgZGF0YXNldCB3aGVyZSBhcnRpZmljaWFsIGRvdWJsZXRzIGFyZSBhZGRlZCB0byB0aGUgbWl4LiBCeSBkb2luZyBzbywgdGhlIGFydGlmaWNpYWwgZG91YmxldHMgcmVzZW1ibGUgZHJvcGxldHMgdGhhdCBtYXkgY29udGFpbiB0d28gY29tcGxldGVseSBkaWZmZXJlbnQgY2VsbCB0eXBlcy4gQXJndWFibHksIHRoZSBzYW1lIHByb2Nlc3MgbGlrZWx5IG9jY3VycyBhcyB0cnVlIGRvdWJsZXRzIGZvcm0gaW4gdGhlIG1pY3JvZmx1aWRpYyBjb250YWluZXIuIERvdWJsZXRGaW5kZXIgdGhlbiBjYXJyaWVzIG91dCBQQ0FzIHVzaW5nIG91ciBwcmV2aW91c2x5IGRldGVybWluZWQgb3B0aW1hbCBudW1iZXIgb2YgUEMtZGltZW5zaW9ucyAoZHVyaW5nIHRoZSB1bnN1cGVydmlzZWQgY2x1c3RlcmluZyBzdGVwKS4gVGhlIFBDIGRpc3RhbmNlIG1hdHJpeCBpcyB0aGVuIHVzZWQgdG8gZmluZCBhcnRpZmljaWFsIEstbmVhcmVzdCBuZWlnaGJvcnMgdG8gZGVmaW5lIHdoZXJlIHRoZSB0cnVlIGFuZCB0aGUgYXJ0aWZpY2lhbCBkb3VibGV0cyBzaGFyZSB0aGUgc2FtZSBuZWlnaGJvcmhvb2QuIFRoaXMgc3RlcCBpcyByZWN1cnNpdmUgYW5kIGNvbXB1dGF0aW9uYWwgZXhwZW5zaXZlIGFuZCB0aHVzIHdlIGFsbG93IHRoZSB1c2VyIHRvIGNob29zZSB0aGUgbnVtYmVyIG9mIENQVS1jb3JlcyAoNCBjb3JlcyBieSBkZWZhdWx0KS4gT25jZSBjb21wbGV0ZSwgd2UgcmVtb3ZlIHRoZSBhZGRlZCBhcnRpZmljaWFsIGRvdWJsZXRzIGFuZCB0aGUgcHJlLWRlZmluZWQgcHJvcG9ydGlvbiBvZiBpZGVudGlmaWVkIHJlYWwgZG91YmxldHMgZnJvbSB0aGUgZGF0YXNldC4KCiogU2luY2UgdGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHBlcmNlbnRhZ2Ugb2YgdHJ1ZSBkb3VibGV0cyBhbmQgbnVtYmVyIG9mIHJlY292ZXJlZCBjZWxscyBmb3IgdGhlICJTaW5nbGUgQ2VsbCAzJyBHZW5lIEV4cHJlc3Npb24gQXNzYXkiLCB3ZSBpbXBsZW1lbnRlZCB0aGlzIGxpbmVhcml0eSBpbiB0aGUgYWxnb3JpdGhtIHRvIGVuc3VyZSB0aGUgbW9kZWwgZG9lcyBub3Qgb3ZlciBvciB1bmRlcmVzdGltYXRlIHRoZSB0cnVlIGRvdWJsZXRzIGluIHRoZSBkYXRhc2V0LiAKCiogVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBudW1iZXIgb2YgcmVjb3ZlcmVkIGNlbGxzIGFuZCB0cnVlIGRvdWJsZXRzIGlzIHByb3ZpZGVkIGJ5IDEwWCAoaHR0cHM6Ly9rYi4xMHhnZW5vbWljcy5jb20vaGMvZW4tdXMvYXJ0aWNsZXMvMzYwMDAxMzc4ODExLVdoYXQtaXMtdGhlLW1heGltdW0tbnVtYmVyLW9mLWNlbGxzLXRoYXQtY2FuLWJlLXByb2ZpbGVkLSkuIFdlIG1ha2UgYSBsaW5lYXIgcmVncmVzc2lvbiBmcm9tIHRoaXMgYW5kIGltcGxlbWVudCBpdCBpbnRvIERvdWJsZXRGaW5kZXIuCgoqIFBsZWFzZSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGNvcmVzIGZvciB0aGlzIHN0ZXAgaWYgaGF2ZSBtYW55IGNlbGxzLiBGaW5kaW5nIGFydGlmaWNpYWwgSy1uZWFyZXN0IG5laWdoYm9ycyBkdXJpbmcgdGhlIHBhcmFtZXRlciBzd2VlcCBjYW4gYmUgY29tcHV0YXRpb25hbGx5IGV4cGVuc2l2ZS4gVGhlIG51bWJlciBvZiBjb3JlcyBzaG91bGQgTk9UIGV4Y2VlZCB0aGUgYXZhaWxhYmxlIHJlc291cmNlcyBpbiB5b3VyIHN5c3RlbSBwcm92aWRlZCB0byB0aGUgcGlwZWxpbmUuIElmIHlvdSBkbywgdGhlbiBEb3VibGV0RmluZGVyIHdpbGwgbGlrZWx5IGNyYXNoIQoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogRG91YmxldCBVTUFQIHBsb3Q6IAogIC0gUmVwcmVzZW50aW5nIHRoZSBpZGVudGlmaWVkIGRvdWJsZXRzIHdpdGhpbiB0aGUgcHJlbGltaW5hcnkgY2x1c3Rlci4gT2Z0ZW4sIHRoZSBkb3VibGV0cyBhcmUgbG9jYXRlZCBvbiB0aGUgZWRnZXMgb3IgYmV0d2VlbiBvdGhlciBjZWxsIHBvcHVsYXRpb24uCiAgCiogVmlvbGluIHBsb3RzOgogIC0gUmVwcmVzZW50aW5nIHRoZSBzY2F0dGVyZWQgZGlzdHJpYnV0aW9uIG9mIGRvdWJsZXRzIGFuZCBzaW5nbGV0cyBhcyBhIGZ1bmN0aW9uIG9mIGdlbmUgYW5kIHRyYW5zY3JpcHQgY291bnRzLiBIZXJlIGl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIGRvdWJsZXRzIGNvbnRhaW4gbW9yZSBnZW5lcyBhbmQgdHJhbnNjcmlwdHMgd2hlbiBjb21wYXJlZCB0byBzaW5nbGV0cy4KYGBge3IgRG91YmxldGZpbmRlciAtIEZpbmRpbmcgdGhlIG9wdGltYWwgUGsgdmFsdWUgZm9yIGRvdWJsZXRmaW5kZXIsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTEwLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcmVjdXJzaXZlbHkgZGV0ZXJtaW5lcyB0aGUgb3B0aW1hbCBudW1iZXIgb2YgcEsgdmFsdWUgZm9yIHRoZSBwcm9iYWJpbGlzdGljIGRldGVybWluYXRpb24gb2YgbXVsdGlwbGV0cwojIC8vIHBLIGRlZmluZXMgdGhlIFBDIG5laWdoYm9yaG9vZCBzaXplIHVzZWQgdG8gY29tcHV0ZSB0aGUgcHJvcG9ydGlvbiBvZiBhcnRpZmljaWFsIGsgbmVhcmVzdCBuZWlnaGJvcnMgZm9yIGVhY2ggY2VsbCwgZXhwcmVzc2VkIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgbWVyZ2VkIHJlYWwtYXJ0aWZpY2lhbCBkYXRhLgojIC8vIE9wdGltYWwgcEsgdmFsdWVzIGFyZSBhbHdheXMgYmV0d2VlbiAwIGFuZCAwLjMgKDAtMzAlKSBieSBkZWZhdWx0CiMgLy8gcE4gZGVmaW5lcyB0aGUgbnVtYmVyIG9mIGdlbmVyYXRlZCBhcnRpZmljaWFsIGRvdWJsZXRzLCBleHByZXNzZWQgYXMgYSBwcm9wb3J0aW9uIG9mIHRoZSBtZXJnZWQgcmVhbC1hcnRpZmljaWFsIGRhdGEuIERlZmF1bHQgaXMgc2V0IHRvIDI1JSAoaW1wbGVtZW50IHVzZXIgcGFyYW1ldGVyKQojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgTGV0cyBjYWxjdWxhdGUgdGhlIG9wdGltYWwgUGsgdmFsdWUgZm9yIGRvdWJsZXRmaW5kZXIKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBzYW1wbGVfbmFtZXMpKSB7CiAgc3dlZXAucmVzLmxpc3Rfc29iaiA8LSBwYXJhbVN3ZWVwKHNvYmpfbGlzdFtbaV1dLCBQQ3MgPSBwYy5kaW1zW1tpXV0sIHNjdCA9IEZBTFNFLCBudW0uY29yZXMgPSBpZiAoQ1BVLmNvcmVzID49IDAgJiBDUFUuY29yZXMgPD0gOCAmIGlzLm5hKENQVS5jb3JlcykgPT0gRkFMU0UpewogICAgQ1BVLmNvcmVzID0gQ1BVLmNvcmVzfWVsc2V7Q1BVLmNvcmVzID0gMX0pICMgc2V0IENQVSBjb3JlcyAxIGJ5IGRlZmF1bHQsIGJ1dCBubyBoaWdoZXIgdGhhbiA4IGlmIHVkZXIgZGVmaW5lZAogIHN3ZWVwLnN0YXRzX3NvYmogPC0gc3VtbWFyaXplU3dlZXAoc3dlZXAucmVzLmxpc3Rfc29iaiwgR1QgPSBGQUxTRSkKICBiY212bl9zb2JqIDwtIGZpbmQucEsoc3dlZXAuc3RhdHNfc29iaikKCiAgIyBzZWxlY3QgdGhlIHBLIHRoYXQgY29ycmVzcG9uZHMgdG8gbWF4IGJjbXZuIHRvIG9wdGltaXplIGRvdWJsZXQgZGV0ZWN0aW9uCiAgcEsgPC0gYmNtdm5fc29iaiAlPiUgCiAgICBkcGx5cjo6ZmlsdGVyKEJDbWV0cmljID09IG1heChCQ21ldHJpYykpICU+JSAKICAgIGRwbHlyOjpzZWxlY3QocEspIAogIAogIHBLIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHBLW1sxXV0pKSAjIG1ha2UgaW50ZWdlcgogIAogICMgbGV0cyBwbG90IHRvIHNvbyB0aGUgb3B0aW1hbCBQSyB2YWx1ZQogIHBsb3R0dHQgPC0gZ2dwbG90KGJjbXZuX3NvYmosIGFlcyhwSywgQkNtZXRyaWMsIGdyb3VwID0gMSkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9saW5lKCkKICBwcmludChwbG90dHR0KQogIAogICMgRXN0aW1hdGUgdGhlIHByb3BvcnRpb24gb2YgZG91YmxldHMgaW4gb3VyIGRhdGEgYW5kIHJ1biBEb3VibGV0RmluZGVyCiAgY2x1c3RlcnMgPC0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhJHNldXJhdF9jbHVzdGVyICMgcHJldmlvdXMgY2x1c3RlciBmcm9tIFVNQVAKICBkb3VibGV0LnByb3BvdGlvbnMgPC0gbW9kZWxIb21vdHlwaWMoY2x1c3RlcnMpIAogIG5FeHBfcG9pIDwtIHJvdW5kKHBlcmNlbnQubXVsdGlwbGV0c1tbaV1dKm5yb3coc29ial9saXN0W1tpXV1AbWV0YS5kYXRhKSkgICMjIEFzc3VtaW5nIDQuOCUgZG91YmxldCBmb3JtYXRpb24gcmF0ZSAKICBuRXhwX3BvaS5hZGogPC0gcm91bmQobkV4cF9wb2kqKDEtZG91YmxldC5wcm9wb3Rpb25zKSkKICAjIFJ1biBkb3VibGV0ZmluZGVyCiAgCiAgc29ial9saXN0W1tpXV0gPC0gZG91YmxldEZpbmRlcihzb2JqX2xpc3RbW2ldXSwgUENzID0gcGMuZGltc1tbaV1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBLID0gcEssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkV4cCA9IG5FeHBfcG9pLmFkaiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXVzZS5wQU5OID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2N0ID0gRkFMU0UpCn0KYGBgCgpgYGB7ciB2aXN1YWxpemUgdGhlIG51bWJlciBvZiBkb3VibGV0cyBpbiBjbHVzdGVyLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD02LCBlY2hvPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHZpc3VhbGl6ZWQgdGhlIHRydWUgaWRlbnRpZmllZCBtdWx0aXBsZXRzIGluIHZpb2xpbiBwbG90IGFuZCBVTUFQIHNwYWNlCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJuIGEgdmlvbGluIGFuZCBVTUFQIHBsb3Qgb2YgdGhlIGlkZW50aWZpZWQgbXVsdGlwbGV0cyBieSBEb3VibGV0RmluZGVyCiMgLy8gSW5wdXQgZmlsZSBtdXN0IGJlIGEgdmVjdG9yIG9mIFNldXJhdCBvYmplY3RzIHRoYXQgaGF2ZSBiZWVuIHVzZWQgaW5wdXQgZm9yIERvdWJsZXRGaW5kZXIKc2hvd19kb3VibGV0cyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgY29sbmFtZXMoc29iakBtZXRhLmRhdGEpW2xlbmd0aChzb2JqQG1ldGEuZGF0YSldIDwtIGFzLmNoYXJhY3Rlcihzb2JqQG1ldGEuZGF0YVsxLDFdKSAjIGNoYW5nZSBjb2x1bW4gbmFtZSBvZiBtdWx0aXBsZXQgY2hhbm5lbCB0byBzYW1wbGUgbmFtZQogIG11bHRpcGxldC5jaGFubmVsIDwtIGNvbG5hbWVzKHNvYmpAbWV0YS5kYXRhKVtsZW5ndGgoc29iakBtZXRhLmRhdGEpXSAjIGNvbHVtbiA4IG9mIHRoZSBzZXVyYXQgb2JqZWN0QG1ldGFkYXRhIGNvcmVzcG9uZHMgdG8gdGhlIGRvdWJsZXQgY2hhbm5lbAogIAogICMgVU1BUCBwbG90IHRoZSBkb3VibGV0cyBhbmQgc2luZ2xldHMgdXNpbmcgdGhlIG9yaWdpbmFsIGxvdmFpbiBVTUFQIHBsb3QKICBkb3VibGV0X3Bsb3QgPC0gRGltUGxvdChzb2JqLCByZWR1Y3Rpb24gPSAndW1hcCcsIGdyb3VwLmJ5ID0gbXVsdGlwbGV0LmNoYW5uZWwsIHB0LnNpemUgPSAwLjA1KSArIAogICAgZ2d0aXRsZShwYXN0ZSgiTXVsdGlwbGV0IERldGVjdGlvbjogVU1BUDoiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiICIpLCAKICAgICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZSh0YWJsZShzb2JqQG1ldGEuZGF0YVtsZW5ndGgoc29iakBtZXRhLmRhdGEpXSlbMV0sIHBhc3RlKHRhYmxlKHNvYmpAbWV0YS5kYXRhW2xlbmd0aChzb2JqQG1ldGEuZGF0YSldKVsyXSwgIk11bHRpcGxldHMiKSwgc2VwID0gIi8iKSkgKyAKICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCiAgcHJpbnQoZG91YmxldF9wbG90KQogIAogICMgcGxvdCB2aW9saW4gb2YgbnVtYmVyIG9mIGdlbmVzL1VNSXMgZm9yIGRvdWJsZXRzIGFuZCBzaW5nbGV0cwogIHYxLjEgPC0gVmxuUGxvdChzb2JqLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLCBncm91cC5ieSA9IG11bHRpcGxldC5jaGFubmVsLCBwdC5zaXplID0gMC4xKSArIAogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQogIHYxLjIgPC0gVmxuUGxvdChzb2JqLCBmZWF0dXJlcyA9ICJuQ291bnRfUk5BIiwgZ3JvdXAuYnkgPSBtdWx0aXBsZXQuY2hhbm5lbCwgcHQuc2l6ZSA9IDAuMSkgKyAKICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKICBwcmludCh2MS4xKQogIHByaW50KHYxLjIpCiAgCiAgIyBzaG93IHRoZSBudW1iZXIgb2YgYWN0dWFsIGRvdWJsZXRzIGluIHRoZSBkYXRhCiAgcHJpbnQodGFibGUoc29iakBtZXRhLmRhdGFbbGVuZ3RoKHNvYmpAbWV0YS5kYXRhKV0pKQogIAogIHJldHVybigpCn0KIyBFeGVjdXRlIHNob3dfZG91YmxldHMgZnVuY3Rpb24KZG91YmxldF9yZXN1bHQgPC0gc2FwcGx5KHNvYmpfbGlzdCwgc2hvd19kb3VibGV0cykKYGBgCgojIyMjIEZpbmFsIGZpbHRlcmluZyBhbmQgUUMgcGxvdHMgIyMjIwoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogSW4gdGhlIGNodWNrIGJlbG93LCB3ZSB3aWxsIGRvIGFub3RoZXIgZGF0YSBmaWx0ZXJpbmcgYnkgdGFraW5nIG91dCB0aGUgaWRlbnRpZmllZCBtdXVsdGlwbGV0cyBpbiB0aGUgZGF0YXNldC4KICAtIE5vdyB5b3UgaGF2ZSBjYW4gZmluYWxseSBjb21wYXJlIHlvdXIgcmVzdWx0cyBhbmQgbnVtYmVyIG9mIGNlbGxzIGJlZm9yZSBhbmQgYWZ0ZXIgZmlsdGVyaW5nLiBJdCBnaXZlcyB5b3UgYW4gaWRlYSBob3cgYWdncmVzc2l2ZWx5IHlvdSBoYXZlIGZpbHRlcmVkIHlvdXIgZGF0YS4gCiAgLSBMaWtld2lzZSwgeW91IGNhbiBjb21wYXJlIHRoZSBRQyBwbG90cyB0byB3aGF0IGhhZCBiZWZvcmUuIERvIHlvdSBzZWUgYW55IGltcHJvdmVtZW50IGhlcmU/IAogIC0gUmVtZW1iZXIgdGhhdCB5b3UgY2FuIGFsd2F5cyBjaGFuZ2UgdGhlIHBhcmFtZXRlcnMgdG8geW91ciBsaWtpbmcgYW4gcnVuIGl0IGFnYWluLgogIAoqIEl0IGlzIGFkdmlzZWQgdG8gdHJ5IHRvIGFubm90YXRlIHlvdSBjZWxscyB1c2luZyB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhIGFuZCBzZWUgaWYgeW91IGZpbmQgeW91ciBleHBlY3RlZCBjZWxscyAoaW4gdGhlIHJpZ2h0IHByb3BvcnRpb24pLiBJZiB5b3UgdGhpbmsgdGhhdCB5b3UgYXJlIG1pc3Npbmcgc29tZSByYXJlIGNlbGxzIHRoYXQgY29udGFpbiBmZXcgZ2VuZXMvdHJhbnNjcmlwdHMsIHRoZW4gdHJ5IHRvIHVzZSB0aGUgcmF3IGNvdW50cyBtYXRyaXggYXMgYSBzdGFydGluZyBwb2ludC4gVGhpcyB3aWxsIGxpa2VseSBleHBvc2UgdGhvc2UgY2VsbHMgdGhhdCBoYXZlIGJlZW4gZmlsdGVyZWQgb3V0IGJ5IENlbGxyYW5nZXJzIDUwMCBVTUkgdGhyZXNob2xkLiBCeSB1c2luZyB0aGUgcmF3IG1hdHJpeCwgdGhlIHBpcGVsaW5lIHdpbGwgYXV0b21hdGljYWxseSByZW1vdmUgYWxsIGNlbGxzIHRoYXQgaGF2ZSA8MTAwIGdlbmVzLiBCeSBkb2luZyBzbywgd2UgZW5zdXJlIHRoYXQgeW91IGRvIG5vdCBlbmQgdXAgbWFueSBsb3cgcXVhbGl0eSBkcm9wbGV0cy4gRXZlbiB0aGUgcmFyZXN0IGNlbGxzIHVzdWFsbHkgZG8gbm90IGNvbnRhaW4gbGVzcyB0aGFuIDEwMCBnZW5lcyBhbnl3YXkuIEZlZWwgZnJlZSB0byBkaXNhZ3JlZSBhbmQgY2hhbmdlIHRoZSBwYXJhbWV0ZXIgdG8geW91ciBsaWtpbmcuIElmIHlvdSBkbyBub3QgY2hhbmdlIGFueXRoaW5nLCB0aGVuIHRoZSB0aHJlc2hvbGQgaXMgYWx3YXlzIHNldCBhdCAxMDAgZ2VuZXMuIE5FVkVSIFRPVUNIIFRISVMgUEFSQU1FVEVSIElGIFlPVSBBRUUgV09SS0lORyBXSVRIIFRIRSBGSUxURVJFRCBDT1VOVFMgTUFUUklYISBZb3Ugd2lsbCBhbHdheXMgbG9zZSBjZWxscyB0aGF0IGNvbnRhaW4gZmV3IGdlbmVzL3RyYW5zY3JpcHRzLiAKYGBge3IgZmlsdGVyIGFuZCByZW1vdmUgZG91YmxldHMgaW4gdGhlIGRhdGEsIGZpZy5oZWlnaHQ9OSwgZmlnLndpZHRoPTE3LCBlY2hvPUZBTFNFfSAKIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBzYXZlcyB0aGUgZmluYWwgb3V0cHV0IGNvdW50IG1hdHJpeCB0aGF0IGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCAoZmlsdGVyZWQpLCBjb3JyZWN0ZWQgZm9yIGFtYmllbnQgUk5BIGFuZCByZW1vdmVkIG11bHRpcGxldHMKIyAvLyBBZGRpdGlvbmFsbHksIHRoZSBmdWxseSBwcm9jZXNzZWQgb2JqZWN0IHdpbGwgYmUgdXNlZCB0aGUgcGxvdCBhbGwgdGhlIHByZXZpb3VzIFFDIHBsb3RzIHBsb3RzIHdoZXJlIHRoZSB1c2VyIGNhbiB2aXN1YWxseSBjb21wYXJlIHRoZSBwcmUgdnMgcG9zdCBmaWx0ZXJpbmcKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBpZiAoc2tpcC5Eb3VibGV0RmluZGVyID09ICJ5ZXMiICYgc3RyX2xlbmd0aChza2lwLkRvdWJsZXRGaW5kZXIpICE9IDApIHsgIyBJZiB3ZSBoYXZlIGxvdyBjb21wbGV4aXR5IGRhdGEgb3Igd3JvbmcgcGFyYW1ldGVyIGdpdmVuLCB0aGVuIFNvdXBYIHdpbGwgYmUgc2tpcHBlZAogICAgcHJpbnQoIkNvcnJlY3Rpb24gZm9yIG11bHRpcGxldHMgd2lsbCBub3QgYmUgY2FycmllZCBvdXQiKQogICAgIyBJZiB0aGVyZSBpcyBhIGRpcmVjdG9yeSwgdGhlbiBtYWtlIG5ldyBvbmUgYW5kIHNhdmUgU2VtaSBmaWx0ZXJlZCBtYXRyaXggCiAgICBpZiAoZGlyLmV4aXN0cyhmaWxlLnBhdGgocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpKSkpIHsKICAgICAgd3JpdGUxMHhDb3VudHMocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzL1NlbWlGaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0gZWxzZSB7ICMgZWxzZSBtYWtlIGRpcmVjdG9yeSBhbmQgc2F2ZSBTZW1pIGZpbHRlcmVkIG1hdHJpeAogICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSksIHJlY3Vyc2l2ZSA9IFRSVUUpCiAgICAgICAgd3JpdGUxMHhDb3VudHMocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzL1NlbWlGaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0KICB9IGVsc2UgewogICAgIyBmaWx0ZXIgb3V0IHRoZSBtdWx0aXBsZXRzCiAgICBjb2xuYW1lcyhzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGEpW2xlbmd0aChzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGEpXSA8LSAibXVsdGlwbGV0cyIgIyBNYWtlIGNvbG5hbWVzIG9mIG11bHRpcGxldCBjaGFubmVsIHVuaXZlcnNhbCBmb3IgYWxsIFNldXJhdCBvYmplY3RzCiAgICBzb2JqX2xpc3RbW2ldXSA8LSBzdWJzZXQoc29ial9saXN0W1tpXV0sIHN1YnNldCA9IG11bHRpcGxldHMgPT0gIlNpbmdsZXQiKSAjIHJlbW92ZSBkb3VibGV0cyBieSBrZWVwaW5nICJzaW5nbGV0cyIKICAgIHByaW50KHNvYmpfbGlzdFtpXSkKICAgICMgU2F2ZSB0aGUgZmluYWwgY29ycmVjdGVkIE1hdHJpeAogICAgaWYgKGRpci5leGlzdHMoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSkpKSB7CiAgICAgIHdyaXRlMTB4Q291bnRzKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cy9GaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGlyLmNyZWF0ZShmaWxlLnBhdGgocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpKSwgcmVjdXJzaXZlID0gVFJVRSkKICAgICAgICB3cml0ZTEweENvdW50cyhwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMvRmlsdGVyZWRDb3VudHMiLCBzZXAgPSAiIiksIHNlcCA9ICIvIiksIHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzLCB2ZXJzaW9uID0gIjMiLCBvdmVyd3JpdGUgPSBUUlVFKQogICAgICB9CiAgICB9CiAgfQoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBRQyBwbG90cyBvZiB0aGUgcHJlIHByb2NjZXNlZCAoZmlsdGVyZWQpIFNldXJhdCBvYmplY3QKIyAvLyBSZXR1cm5zIGhpc3RvZ3JhbSBvZiBjZWxsIGZyZXF1ZW5jeSB2cyBNVCwgblVNSSBhbmQgbkdlbmUKIyAvLyBSZXR1cm4gYSB2aW9saW4gcGxvdCBvZiBjZWxsIGRpc3RyaWJ1dGlvbiBhcyBhIGZ1bmN0aW9uIG9mIE1UIGNvbmMsIG5VTUksIG5HZW5lIAojIC8vIFJldHVybiBhIHNjYXR0ZXIgcGxvdCBvZiBjZWxscyBiYXNlZCBvbiBuVU1JcyB2cyBuR2VuZXMgKGFsc28gaW4gTG9nMTAgc2NhbGVkKSAKIyAvLyBSZXR1cm4gYSBzY2F0dGVyIHBsb3Qgb2YgY2VsbHMgYmFzZWQgb24gJU1UIHZzIG5HZW5lcyBvciBuVU1JcwojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cyB0aGF0IGhhdmUgYmVlbiBwcmUgcHJvY2Vzc2VkCmdldF92aW9sX1FDIDwtIGZ1bmN0aW9uKHNvYmosIGZldS51cCwgdW1pLnVwLCBmZXUubG93LCB1bWkubG93KSB7CiAgc29iaiA8LSBTZXRJZGVudChzb2JqLCB2YWx1ZSA9IHNvYmpAbWV0YS5kYXRhJG9yaWcuaWRlbnQpICMgY2hhbmdlIGFjdGl2ZS5pZGVudCB0byBvcmlnLmlkZW50LCBhcyB0aGUgYWN0aXZlLmlkZW50IGhhcyBiZWVuIGNoYW5nZWQgYWZ0ZXIgdGhlIExvdmFpbiBjbHVzdGVyaW5nLgogIHYxIDwtIFZsblBsb3Qoc29iaiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzLCBjb2xzID0gIm1hZ2VudGEiKQogIAogIGFzX3RpYmJsZShzb2JqW1tdXSwgcm93bmFtZXM9IkNlbGwuQmFyY29kZSIpIC0+IHFjLm1ldHJpY3MgIyBzb2JqX2xpc3RbWzFdXVtbXV0gc2hvd3MgZGF0YS5mcmFtZSBvZiBtZXRhZGF0YQogIHAxIDwtIHFjLm1ldHJpY3MgJT4lCiAgICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogICAgZ2dwbG90KGFlcyhuQ291bnRfUk5BLG5GZWF0dXJlX1JOQSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdibGFjaycsICdyZWQzJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogOTUpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IG5VTUlzIHZzIG5HZW5lcyB3aXRoIHBlcmNlbnQgTVQiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyMDAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZmV1LnVwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBmZXUubG93LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1NTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gdW1pLnVwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHVtaS5sb3csIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgCiAgICB0aGVtZV9idygpICsgIyBtYWtlIGZpbGxlciB3aGl0ZQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgIyByZW1vdmUgcmFzdGVyCiAgCiAgICBwMS4xIDwtIHFjLm1ldHJpY3MgJT4lCiAgICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogICAgZ2dwbG90KGFlcyhsb2cxMChuQ291bnRfUk5BKSwgbG9nMTAobkZlYXR1cmVfUk5BKSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdibGFjaycsICdyZWQzJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogOTUpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IExvZzEwIHNjYWxlZCBuVU1JcyB2cyBuR2VuZXMgd2l0aCBwZXJjZW50IE1UIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMCgyMDApLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0wLjcpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS51cCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAoZmV1LmxvdyksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKyAKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKDU1MCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLnVwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMCh1bWkubG93KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgICB4bGFiKCJMb2cxMCAoTnVtYmVyIG9mIFVNSXMpIikgKyAKICAgIHRoZW1lX2J3KCkgKyAjIG1ha2UgZmlsbGVyIHdoaXRlCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAgIyByZW1vdmUgcmFzdGVyCiAgCiAgICBoMSA8LSBoaXN0KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQsIGJyZWFrcyA9IDMwLCB4bGFiID0gIlBlcmNlbnRhZ2UgTWl0b2Nob25kcmlhbCBHZW5lcyAoJSkiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiAgICAgICAgICAgICBtYWluID0gcGFzdGUoIlBPU1QtRklMVEVSSU5HOiBRQyBNVCIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSwgCiAgICAgICAgICAgICBjb2wgPSAid2hpdGUiLCBsYWJlbHMgPSBUUlVFLCBwbG90ID0gVFJVRSkKICAgIGFibGluZSh2ID0gMTAsIGNvbD0icmVkIiwgbHdkPTMsIGx0eT0yKQogICAgYWJsaW5lKHYgPSA1LCBjb2w9Im9yYW5nZSIsIGx3ZD0zLCBsdHk9MikKICAgICMgdmlzdWFsaXplIG51bWJlciBvZiBnZW5lcyBpbiBjZWxscwogICAgaDIgPC0gaGlzdChzb2JqW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSwgYnJlYWtzID0gMzAsIHhsYWIgPSAiTnVtYmVyIG9mIGdlbmVzIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJQT1NULUZJTFRFUklORzogUUMgbnVtYmVyIG9mIGdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCAKICAgICAgICAgICAgIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKQogICAgYWJsaW5lKHYgPSAyMDAsIGNvbD0icmVkIiwgbHdkPTMsIGx0eT0yKQogICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIFVNSXMgKG1vbGVjdWxlcykgaW4gY2VsbHMKICAgIGgzIDwtIGhpc3Qoc29ialtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSwgYnJlYWtzID0gMzAsIHhsYWIgPSAiTnVtYmVyIG9mIFVNSXMgKFJOQSBtb2xlY3VsZXMpIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJQT1NULUZJTFRFUklORzogUUMgbnVtYmVyIG9mIFVNSXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICBhYmxpbmUodiA9IDUwMCwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpCiAgICAKICAgIGYuc2NhdC5wcm9jZXNzZWQgPC0gRmVhdHVyZVNjYXR0ZXIoc29iaiwgZmVhdHVyZTEgPSAibkZlYXR1cmVfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IFBlcmNlbnQtTVQgdnMgbkdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MSkgKyAKICAgIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIAogICAgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQogICAgCiAgICBmLnNjYXQucHJvY2Vzc2VkMiA8LSBGZWF0dXJlU2NhdHRlcihzb2JqLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IFBlcmNlbnQtTVQgdnMgblVNSXMiKSkgKyAKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjUsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTEpICsgCiAgICB5bGFiKCJQZXJjZW50IE10aW9jaG9uZHJpYWwgR2VuZXMgKCUpIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgTm9MZWdlbmQoKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKICAgIAogICAgCiAgICBzb2JqJGxvZzEwR2VuZXNQZXJVTUkgPC0gbG9nMTAoc29iaiRuRmVhdHVyZV9STkEpIC8gbG9nMTAoc29iaiRuQ291bnRfUk5BKQogICMgVmlzdWFsaXplIHRoZSBvdmVyYWxsIGNvbXBsZXhpdHkgb2YgdGhlIGdlbmUgZXhwcmVzc2lvbiBieSB2aXN1YWxpemluZyB0aGUgZ2VuZXMgZGV0ZWN0ZWQgcGVyIFVNSQogIHAxLjIgPC0gc29iakBtZXRhLmRhdGEgJT4lCiAgCWdncGxvdChhZXMobG9nMTBHZW5lc1BlclVNSSkpICsKICAJZ2VvbV9kZW5zaXR5KGFscGhhID0gMSwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xLjUpICsKICAJdGhlbWVfY2xhc3NpYygpICsKICAJZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC44LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArCiAgICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5IFBsb3Q6Iiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAiKSkgKyAKICAgIHlsYWIoIkRlbnNpdHkiKSArIAogICAgeGxhYigiTG9nMTAgR2VuZXMvVU1JIChHZW5lcyBwZXIgVU1JKSIpCiAgCiAgIyBMZXQgdGFrZSBhIGNsb3NlciBsb29rIGF0IHRoZSBjb21wbGV4aXR5IG9mIHRoZSBkYXRhIGFuZCBkcml2ZW4gYnkgd2hhdCBnZW5lLiAKICAjIENhbGN1bGF0ZSBjYWxjdWxhdGUgdGhlIGxvZzEwKG5GZWF0dXJlX1JOQSkgLyBsb2cxMChuQ291bnRfUk5BKSkgYW5kIHB1dCBpbiB0aGUgcWMubWV0cmljCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHk9bG9nMTAobkZlYXR1cmVfUk5BKSAvIGxvZzEwKG5Db3VudF9STkEpKSAgLT4gcWMubWV0cmljcwogICMgTWFrZSBsaW5lYXIgbW9kZWxzIG9mIGxvZzEwKG5GZWF1dHVyZXMpIHZzIExvZzEwKG5VTUlzKSBhbmQgcHV0IGluIHB1dCBpbiBjb21wbGV4aXR5LmxtCiAgIyBIZXJlLCB3ZSBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UgZnJvbSB0aGUgb2JzZXJ2ZWQgdmFsdWUgdG8gdGhlIGV4cGVjdGVkCiAgbG0obG9nMTAocWMubWV0cmljcyRuRmVhdHVyZV9STkEpfmxvZzEwKHFjLm1ldHJpY3MkbkNvdW50X1JOQSkpIC0+IGNvbXBsZXhpdHkubG0KICAjIENhbGN1bGF0ZSB0aGUgY29tcGxleGl0eSBmcm9tIHRoZSBtaWRkbGUgbGluZSBvZiB0aGUgbGluZWFyIG1vZGVsCiAgIyBXZSB3aWxsIHVzZSB0aGlzIGZvciB0aGUgY29sb3Igc2NhbGUgb2YgdGhlIGdyYXBoIGFzIHdlbGwuCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHlfZGlmZiA9IGxvZzEwKG5GZWF0dXJlX1JOQSkgLSAoKGxvZzEwKHFjLm1ldHJpY3MkbkNvdW50X1JOQSkqY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMl0pK2NvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzFdKQogICkgLT4gcWMubWV0cmljcwogICMgRmluZCB0aGUgZGVsdGEgZGlmZmVyZW5jZSBmb3IgdGhlIGdyYXBoCiAgbWluKGMobWF4KHFjLm1ldHJpY3MkY29tcGxleGl0eV9kaWZmKSwwLW1pbihxYy5tZXRyaWNzJGNvbXBsZXhpdHlfZGlmZikpKSAtPiBjb21wbGV4aXR5X3NjYWxlCgogICMgSGVyZSB3ZSB2aXN1YWxpemUgdGhlIHRoZSBkYXRhIGNvbXBsZXhpdHkgKGNlbGxzKSBiYXNlZCBvbiB0aGUgY2FsY3VsYXRpb25zIGFib3ZlCiAgcDEuMyA8LSBxYy5tZXRyaWNzICU+JSAKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHlfZGlmZj1yZXBsYWNlKGNvbXBsZXhpdHlfZGlmZixjb21wbGV4aXR5X2RpZmY8IC0wLjUsLTAuNSkpICU+JQogIGdncGxvdChhZXMoeD1sb2cxMChuQ291bnRfUk5BKSwgeT1sb2cxMChuRmVhdHVyZV9STkEpLCBjb2xvdXI9Y29tcGxleGl0eV9kaWZmKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9Y29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMl0sIGludGVyY2VwdCA9IGNvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzFdKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3c9ImJsdWUyIixtaWQ9ImdyZXkiLGhpZ2g9InJlZDIiKSArCiAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eTogTG9nMTAgLSBuVU1JcyB2cyBuR2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgeWxhYigiTG9nMTAgKE51bWJlciBvZiBHZW5lcykiKSArIAogIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKICAjIEhlcmUgd2UgdmlzdWFsaXplIHRoZSBkZW5zaXR5IHBsb3Qgb2YgdGhlIGNlbGxzIGZyb20gdGhlIG1pZGRsZSBvZiB0aGUgbGluZWFyIGdyYXBoIGZyb20gUDEuMwogIHAxLjQgPC0gcWMubWV0cmljcyAlPiUgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZikpICsgCiAgZ2VvbV9kZW5zaXR5KGZpbGw9InllbGxvdyIpICsKICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbCB2cyBEZW5zaXR5IikpICsgCiAgeWxhYigiRGVuc2l0eSIpICsgCiAgeGxhYigiQ29tcGxleGl0eSBEaWZmZXJlbmNlIChSZXNpZHVhbHMpIikgKyAKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkKICAKICAjIE5vdyBsZXRzIHdoaWNoIGdlbmVzIGFyZSBhY3R1YWxseSBkcml2aW5nIHRoZSBsb3cgY29tcGxleGl0eSBjZWxscyBpbiB0aGUgZGF0YQogICMgRm9yIHRoaXMsIHdlIGZpcnN0IGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBvZiBsYXJnZXN0IGdlbmVzLgogICMgRmluZCB0aGUgY2VsbHMgd2l0aCBsYXJnZXN0IGNvdW50cwogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2NvdW50ID0gYXBwbHkoc29iakBhc3NheXMkUk5BQGxheWVycyRjb3VudHMsIDIsIG1heCkpIC0+IHFjLm1ldHJpY3MgIyAiMiIgaXMgdG8gcmV0dXJuIG1heCBjb2x1bW5zIHZhbHVlcwogICMgZmluZCB0aGUgaW5kZXggb2YgdGhlIGNlbGwgd2l0aCBsYXJnZXN0IGNvdW50cwogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2luZGV4ID0gYXBwbHkoc29iakBhc3NheXMkUk5BQGxheWVycyRjb3VudHMsIDIsIHdoaWNoLm1heCkpIC0+IHFjLm1ldHJpY3MKICAjIFVzZSB0aGUgaW5kZXggYW5kIGdldCB0aGUgZ2VuZSBuYW1lIHRoYXQgYWNjb3VudHMgZm9yIHRoZSBsYXJnZXN0IGNvdW50cyBwZXIgY2VsbAogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2dlbmUgPSByb3duYW1lcyhzb2JqKVtsYXJnZXN0X2luZGV4XSkgLT4gcWMubWV0cmljcwogICMgTm93IGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSByZWxhdGl2ZSB0byB0aGUgdG90YWwgY291bnRzIGluIHRoZSBkYXRhCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKHBlcmNlbnQuTGFyZ2VzdC5HZW5lID0gIDEwMCAqIGxhcmdlc3RfY291bnQgLyBuQ291bnRfUk5BKSAtPiBxYy5tZXRyaWNzCiAgCiAgIyBWaXN1YWxpemUgdGhlIGNvbXBsZXhpdHkgZXhwbGFpbmVkIGJ5IHBlcmNlbnRhZ2Ugb2YgbGFyZ2VzdCBnZW5lcwogIHAxLjUgPC0gcWMubWV0cmljcyAlPiUgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZiwgeT1wZXJjZW50Lkxhcmdlc3QuR2VuZSkpICsgCiAgICBnZW9tX3BvaW50KCkgKwogICAgZ2d0aXRsZShwYXN0ZSgiUmVzaWR1YWxzIHZzIFBlcmNlbnRhZ2UgTGFyZ2VzdCBHZW5lcyIpKSArIAogICAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICAgIHhsYWIoIkNvbXBsZXhpdHkgRGlmZmVyZW5jZSAoUmVzaWR1YWxzKSIpICsgCiAgICB0aGVtZV9idygpICsgCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgU29ydCB0aGUgcGVyY2VudGFnZSBsYXJnZXN0IGdlbmVzIAogIHFjLm1ldHJpY3MgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGxhcmdlc3RfZ2VuZSkgJT4lIGRwbHlyOjphcnJhbmdlKGRlc2MocGVyY2VudC5MYXJnZXN0LkdlbmUpKSAtPiBsYXJnZXN0X2dlbmVfbGlzdAogICMgRmlsdGVyIG91dCB0aGUgZ2VuZXMgPjUlIGNvdW50cyAKICBsYXJnZXN0X2dlbmVfbGlzdCAlPiUKICBkcGx5cjo6ZmlsdGVyKHBlcmNlbnQuTGFyZ2VzdC5HZW5lID4gMC41KSAlPiUgIyBmaWx0ZXIgZXhpc3RzIGluIG90aGVyIHBhY2thZ2VzLCB1c2UgZHBseXI6OiB0byBmaXgKICBkcGx5cjo6cHVsbChsYXJnZXN0X2dlbmUpIC0+IGxhcmdlc3RfZ2VuZXNfdG9fcGxvdAogIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCA8LSB1bmlxdWUobGFyZ2VzdF9nZW5lc190b19wbG90KVsxOjhdICMgUmVtb3ZlIGR1cGxpY2F0ZWQgZ2VuZSBuYW1lcyBhbmQgdGFrZSB1cCB0byAxMCBnZW5lcwogIAogICMgUGxvdCB0aGUgbGluZWFyIGNvbXBsZXhpdHkgbW9kZWwgdGhhdCBleHBsYWluIHRoZSBkZXZpYXRpb24gYnkgdGhlIGxhcmdlc3QgZ2VuZXMKICBwMS42IDwtIHFjLm1ldHJpY3MgJT4lCiAgZHBseXI6OmZpbHRlcihsYXJnZXN0X2dlbmUgJWluJSBsYXJnZXN0X2dlbmVzX3RvX3Bsb3QpICU+JQogIGRwbHlyOjptdXRhdGUobGFyZ2VzdF9nZW5lPWZhY3RvcihsYXJnZXN0X2dlbmUsIGxldmVscz1sYXJnZXN0X2dlbmVzX3RvX3Bsb3QpKSAlPiUKICBkcGx5cjo6YXJyYW5nZShsYXJnZXN0X2dlbmUpICU+JQogIGdncGxvdChhZXMoeD1sb2cxMChuQ291bnRfUk5BKSwgeT1sb2cxMChuRmVhdHVyZV9STkEpLCBjb2xvdXI9bGFyZ2VzdF9nZW5lKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0xLjUpICsKICBnZW9tX2FibGluZShzbG9wZT1jb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSwgaW50ZXJjZXB0ID0gY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pICsgI2ltcG9ydCB0aGUgbGluZSBmb3JtIGxpbmVhciBtb2RlbCBmcm9tIGJlZm9yZQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKDIwMCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS51cCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS5sb3cpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLnVwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLmxvdyksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoImdyZXkiLFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCg5LCJTZXQxIikpKSArCiAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eSBieSBMYXJnZXN0IEdlbmUiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgeWxhYigiTG9nMTAgKE51bWJlciBvZiBHZW5lcykiKSArIAogIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAKICAgIAogICMgTm93IHBsb3QgYSBzY2F0dGVyIG9mIHRoZSBjZWxscyB3aXRoIHRoZSByZXNpZHVhbHMgb24gdGhlIHgtYXhpcyBhbmQgcGVyY2VudGFnZSBsYXJnZXN0IGdlbmUgaW4gdGhlIHktYXhpcwogIHAxLjcgPC0gcWMubWV0cmljcyAlPiUKICBkcGx5cjo6ZmlsdGVyKGxhcmdlc3RfZ2VuZSAlaW4lIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkgJT4lCiAgZHBseXI6Om11dGF0ZShsYXJnZXN0X2dlbmU9ZmFjdG9yKGxhcmdlc3RfZ2VuZSwgbGV2ZWxzPWxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkpICU+JQogIGRwbHlyOjphcnJhbmdlKGxhcmdlc3RfZ2VuZSkgJT4lCiAgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZiwgeT1wZXJjZW50Lkxhcmdlc3QuR2VuZSwgY29sb3VyPWxhcmdlc3RfZ2VuZSkpICsKICBnZW9tX3BvaW50KHNpemU9MS41KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiZ3JleSIsUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksIlNldDEiKSkpICsgCiAgZ2d0aXRsZShwYXN0ZSgiUmVzaWR1YWwgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgU2FtZSBhcyBhYm92ZSwgYnV0IG5vdyB3aXRoIHBlcmNlbnRhZ2UuTVQgYXMgZ3JhZGllbnQKICBwMS44IDwtIHFjLm1ldHJpY3MgJT4lCiAgYXJyYW5nZShwZXJjZW50Lm10KSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lLCBjb2xvdXI9cGVyY2VudC5tdCkpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX2NvbG91cl9ncmFkaWVudG4oY29sb3VycyA9IGMoJ2JsYWNrJywgJ2JsYWNrJywgJ3JlZDMnKSwgdmFsdWVzID0gYygwLCAoKChtYXgoc29ialtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgKiA5NSkgLyAxMDApIC8gMTApLCAxKSkgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFscyB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMgKyBNVCAlIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogICAgCiAgIyBQcmludCB0aGUgcGxvdHMKICBwcmludCh2MSkKICBwcmludChmLnNjYXQucHJvY2Vzc2VkICsgZi5zY2F0LnByb2Nlc3NlZDIpCiAgcHJpbnQocDEgKyBwMS4xKQogIHByaW50KHAxLjIpCiAgcHJpbnQocDEuMyArIHAxLjQgKyBwMS41KQogIHByaW50KHAxLjYgKyBwMS43ICsgcDEuOCkKICAKICByZXR1cm4oKQp9CgojIEFwcGx5IGZ1bmN0aW9uIGdldF92aW9sX1FDCiN2aW9sIDwtIHNhcHBseShzb2JqX2xpc3QsIGdldF92aW9sX1FDKQp2aW9sIDwtIG1hcHBseShnZXRfdmlvbF9RQywgc29ial9saXN0LCBmZWF0dXJlLnF1YW50aWxlLmFibGluZSwgVU1JLnF1YW50aWxlLmFibGluZSwgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93LCBVTUkucXVhbnRpbGUuYWJsaW5lLmxvdykgIyBtYXBwbHkgZm9yIG11bHRpcGxlIHZhcmlhYmxlcyBhcyB2ZWN0b3JzCmBgYAo=